Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

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. 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. 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 is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Build your own CAB, Design Patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.backlinkschecker.ws/backlinks/buylinks.html Purchase High PR Backlink

    I like this blog

  • Arun Nair

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