CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Build your own CAB #17: Boil down the "wiring" to a Registry

The other umpteen parts of the series are here in the Table of Contents

A large part of building a composite application is "wiring" the pieces together.  You're wiring views to presenters, commands to menus, and security rules to elements of the screen.  Since you're trying to make this work faster, you make a lot of this work declarative in nature.  Great.  Now let's talk about how you do that wiring.  You can use some attributes, xml configuration, or use some sort of in code registry.  All of that declarative wiring configuration is the "story" of your application.  To understand what the application is doing and has, you have to know and understand the entire story.  My feeling is that you need to minimize the surface area of the wiring configuration.  As much as possible, I want the wiring information centralized into the smallest area of the code as possible. 

As a negative example, take the idea of using declarative attributes.  It's easy to write them, but where's the important information now?  Everywhere.  All over the place.  It's easy to create that behavior with the attributes, but how do you understand what the application as a whole is doing after the initial write?  You can beat the problem by creating "visualizers" that analyze the code and tell you the entire "story" of the application.  That's a fallback solution, and extra work that you can avoid. 

My very strong preference is to use what I call a Registry (I'm not sure that this is quite the same usage of the pattern that Fowler calls a Registry.  I'd be happy to get some feedback about this terminology).  In StoryTeller I have a TreeView control on the left strip of the application that acts as like the solution explorer in Visual Studio.  When one of the TreeNode's is clicked or right-clicked StoryTeller exposes menu items that will execute Commands (Jeremy's Law of Software Design:  all systems want to have an ICommand interface).  I found myself frequently adding new ICommand's to the context menus, and wanted a declarative way to just say that a particular TreeNode executes these ICommand's.  After a couple iterations, I arrived at using a class called the MenuRegistry that I use to wire up the TreeView menus that exposes a very simple fluent interface to attach commands to the different types of TreeNode's.  The code (as of 1/14/2008) that specifies the comamnd to menu wiring is shown below:

 

        protected override void configure()
        {
            registerTypes();
 
            AddCommand<AddExistingProjectCommand>().AppliesTo<HierarchyNode>();
            AddCommand<CreateNewProjectCommand>().AppliesTo<HierarchyNode>();
            AddQueuedCommand<RunAllTestsCommand>().AppliesTo<HierarchyNode>();
            AddCommand<ImportFitnesseCommand>().AppliesTo<HierarchyNode>();
 
            AddCommand<RemoveProjectCommand>().AppliesTo<SystemUnderTestNode>();
            AddCommand<EditProjectPropertiesCommand>().AppliesTo<SystemUnderTestNode>();
 
            AddQueuedCommand<ExecuteTestCommand>().AppliesTo<TestNode>();
 
            AddCommand<AddTestCommand>().AppliesTo<SuiteNode>();
            AddCommand<AddSuiteCommand>()
                .AppliesTo<SuiteNode>()
                .AppliesTo<SystemUnderTestNode>();
 
            AddCommand<AddSetupCommand>().AppliesTo<FragmentGroupNode>();
            AddCommand<AddTearDownCommand>().AppliesTo<FragmentGroupNode>();
            AddCommand<AddNamedFragmentCommand>().AppliesTo<FragmentGroupNode>();
 
 
            AddCommand<DeleteCommand>()
                .AppliesTo<SuiteNode>()
                .AppliesTo<TestNode>()
                .AppliesTo<FragmentNode>();
 
            AddQueuedCommand<BatchRunCommand>()
                .AppliesTo<SystemUnderTestNode>()
                .AppliesTo<SuiteNode>();
        }

If I want to know what's hooked up to the different TreeNode's I can simply go to this one class and scan one method that expresses the wiring information declaratively.  I've put the "signal" that I care about in one place and tucked the dirty "noise" about how the menus get done out of the way. 

There's a lot of mechanics underneath the covers to instantiate the exact ICommand, relate it to the TreeNode that launched it, and build up the Menu on the fly.  I'll write a separate post on that if somebody wants me to, but the important point is that the "story" of what's happening in the menus is boiled down to a little piece of the code. 



Comments

The Build Your Own CAB Series Table of Contents - Jeremy D. Miller -- The Shade Tree Developer said:

Pingback from  The Build Your Own CAB Series Table of Contents - Jeremy D. Miller -- The Shade Tree Developer

# January 15, 2008 2:31 PM

Trumpi's blog said:

I&#39;m quietly spending my last week of leave at home... Agile and Project Management Why do Some Projects

# January 15, 2008 4:10 PM

Reflective Perspective - Chris Alcock » The Morning Brew #11 said:

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #11

# January 16, 2008 3:14 AM

Arun Nair said:

Great Series.  Is the source for MenuRegistry available? When I click on the link it asks for a password.

# April 4, 2008 4:11 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP