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 #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface

The title is a mouthful and accurately implies an alarmingly high jargon to code ration, but I just didn't see anyway to write this post without straying into all of these different subjects.  When you try to write an explanatory article you have to walk a tightrope between a sample problem that's simple enough to work through in no more than a handful of pages and a sample problem that's just too simplistic to be valuable.  I'll leave it up to you to decide which end of the spectrum this one falls on.  I also had a rough time trying to decide on the best way to order the topics in the narrative.  All I can do is ask you to scan the following headers if something seems to be missing or I'm lurching ahead.

Last week I had a flood of people follow Martin Fowler's link into this series.  I thought it was pretty cool because most of my UI patterns material and terminology is transparently based on Fowler's work.  I'm especially glad that Martin didn't mention the fact that I volunteered to help with the UI patterns writing three years ago then disappeared...

If you missed something, here's the Build your own CAB series in its entirety. 

  1. Preamble
  2. The Humble Dialog Box
  3. Supervising Controller
  4. Passive View
  5. Presentation Model
  6. View to Presenter Communication
  7. Answering some questions
  8. What's the Model?
  9. Assigning Responsibilities in a Model View Presenter Architecture
  10. Domain Centric Validation with the Notification Pattern
  11. Unit Testing the UI with NUnitForms
  12. Event Aggregator
  13. Rein in runaway events with the "Latch"
  14. Embedded Controllers with a Dash of DSL
  15. Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface (This Post)
  16. Replacing Data Binding with MicroControllers and the Window Driver Pattern - Forthcoming
  17. Subcutaneous Testing - Forthcoming
  18. Creating the Application Shell - probably a couple posts
  19. Wiring the Components with an IoC tool - Forthcoming, but I may push this off into late summer
  20. A Day in the Life of a Screen

The end is in sight.  In traditional developer style I blew the estimate for how long "Build your own CAB" would take.  I thought all I needed to do was copy n'paste a bunch of verbiage and code from my DevTeach talks into Live Writer and that would be that - but my usual wordiness kicked in and I ended up submitting a completely new talk to DevTeach Vancouver on this subject. 

A couple years ago I remember reading Stephen King say that he always found the Dark Tower books difficult to write as a way of explaining why there was so much lag between new books, much to my exasperation at the time.  I'm obviously not Stephen King, and there's no line of folks wrapped around the corner of CodeBetter waiting for the next installment, but I know how Stephen King felt now.  I do promise that the end of this series won't be as shocking/disappointing/brilliant(?) as the end of the Dark Tower.*

 

Problem Statement

Again, I am not a licensed namer of patterns, and some of the people I've shown this code to have commented that it's reminiscent of Smalltalk UI's, so it's a good bet that some of you have already seen or used similar approaches.  That said, I use the term "MicroController" to refer to a controller class that directs the behavior of a single UI widget.  By itself, a MicroController isn't really that powerful, but like an army of ants, a group of MicroController's working cooperatively (with some external direction) can accomplish powerful feats. 

Here's a common scenario: 

  1. You have a menu bar of some sort or another in the top strip of your composite WinForms application
  2. Each individual menu item needs to fire off a command of some sort (duh)
  3. The availability of some, but not all, menu items is dependent on user roles.  In other words, some menu items will be disabled or hidden if a user does not have a necessary role.
  4. The availability of some menu items is dependent upon the screen that is currently active in an application with some sort of MDI or tabbed interface
  5. The menu bar frequently collects new additions as the application grows

There's nothing in that list that's particularly hard or even unusual, but I want to explore an alternative approach.  Off the top of my head, I've got four goals in mind for the design of my menu state management:

  1. Quickly attach the proper commands and actions to each MenuItem.  This can get tricky because each MenuItem potentially touches and interacts with very different pieces of the application. 
  2. Eliminate duplicate grunge coding.  I say you pursue any chance to eliminate the mechanical cost, and there's quite a bit of repetitive functionality here.
  3. Make the code that specifies the menu behavior as expressive and readable as possible.  This code is going to frequently change, so it's worth our while to make this code readable. 
  4. I want an easy way for each screen to configure the menu state, and I want this menu state calculation and manipulation to be as easy to understand, write, and test as possible.   

Much like the screen state machine sample from my last post, I'm going to try to use a Domain Specific Language (DSL) / Fluent Interface to express and define the menu behavior.  By hiding the mechanics of menu management behind an abstracted Fluent Interface I'm hoping to compress the code that governs the menu state to a smaller area of the code.  I want to be able to understand the menu behavior by scanning a cohesive area of the code.  It's my firm contention that this type of readability simply cannot be accomplished by using the designer to attach bits and pieces of behavior.  Leaning on the designer will scatter the behavior of the screen all over the place.  One of the main reasons I don't like to use the designer or wizards is because you often can't "see" the code and the way it works.

Start with the End in Mind

Before zooming in one the individual components of the solution, let's keep the man firmly behind the curtain and look at my intended end state.  Inside some screen (probably the main Form) is a piece of code that expresses the behavior of the menu items like this fragment below:

        private void configureMenus()
        {
            _menuController.MenuItem(openItem).Executes(CommandNames.Open).IsAlwaysEnabled();
 
            _menuController.MenuItem(saveItem).Executes(CommandNames.Save)
                .IsAvailableToRoles("BigBoss", "WorkerBee");
 
            _menuController.MenuItem(executeItem).Executes(CommandNames.Execute)
                .IsAvailableToRoles("BigBoss");
 
            _menuController.MenuItem(exportItem).Executes(CommandNames.Export);
        }

And in each individual screen presenter you might see some additional code to set screen-specific menu settings like this that would be called upon activating a different screen:

 

    public class SomeScreenPresenter : IPresenter
    {
        public void ConfigureMenu(MenuState state)
        {
            state.Enable(CommandNames.Save, CommandNames.Export);
            state.Enable(CommandNames.Execute).ForRoles("SpecialWorkerBee", "BigBoss");
        }
    }

So what's going on here?  There isn't a single call in this code to MenuItem.Enabled or any definition of MenuItem.Click, so it's safe to assume that there's somebody behind the curtain.  So, what is the man behind the curtain?  Before I talk about each piece in detail, here's a rundown of the various moving parts:

  1. A small MicroController object for each MenuItem that "knows" when to enable or disable its MenuItem and set up the MenuItem's Click event.
  2. A controller class for the menu that aggregates all of the MenuItem controllers.  Part of the responsibility of the Fluent Interface configuration code above is to associate a MenuItem with a CommandNames key so we can quickly reference the correct MenuItem's when a different screen is activated.
  3. A series of Command pattern classes that all implement a common interface. 
  4. StructureMap is lurking in the background as my IoC tool of choice to wire the various parts together.
  5. The Fluent Interface configuration API.  For the most part, it's job is to look pretty.  All it's doing is gathering in input values to set on the individual MenuItem controller classes that do the real work.  What I've found so far is that Fluent Interface strategies seem to lend themselves best to situations like this where you're really just configuring an object graph to do the real work.
  6. A MenuState object that is used to transmit the desired state of the menu from the individual screens to the main menu controller
  7. Each Presenter in the application implements a common interface that includes some sort of hook to configure the items on the main Menu.
  8. The whole application is stitched together with the combination of an ApplicationController and ApplicationShell.  I'm going to be very brief on these two because I'm going to devote a couple posts later down the line to these classes.

 


The complete "Build your own CAB" Table of Contents is now up if you've missed some of the earlier missives.

Continuing where I left off in Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface , I'll show how to build a Fluent Interface API to configure menu state management in a WinForms application while using as many buzzwords as humanly possible.  Going backwards "Memento" style, the end state is shown in the first post (I had to split the content because Community Server whined at me).

Problem Statement 

  1. You have a menu bar of some sort or another in the top strip of your composite WinForms application
  2. Each individual menu item needs to fire off a command of some sort (duh)
  3. The availability of some, but not all, menu items is dependent on user roles.  In other words, some menu items will be disabled or hidden if a user does not have a necessary role.
  4. The availability of some menu items is dependent upon the screen that is currently active in an application with some sort of MDI or tabbed interface
  5. The menu bar frequently collects new additions as the application grows

 

Let's Treat all Presenters Exactly the Same with the Layer SuperType Pattern

From PEAA, a Layer SuperType is

A type that acts as the supertype for all types in its layer.

In all of the WinForms applications I've worked on with Model View Presenter the Presenter's have implemented some sort of Layer Supertype interface or base class.  The details differ quite a bit from project to project, but the pattern seems to always be there.  The methods on the common interface usually relate to setting up screen state or to transitioning between screens.  Here's a sample IPresenter interface that's pretty typical to my projects:

 

    public interface IPresenter
    {
        void ConfigureMenu(MenuState state);
        void Activate();
        void Deactivate();
        bool CanClose();
    }

The Presenter interface is mostly a set of hook methods for the ApplicationController to call to set up or tear down a screen.  While I'll revisit this topic in much more detail later, for now let's focus in on the bolded method in the IPresenter interface above. 

 

Pushing Menu State Around

It's safe to assume that nearly every screen is going to have a different set of rules for which menu items are available and valid for user rules.  By implementing a common interface across all screen Presenter's we can establish a standard way to query a Presenter for its particular menu state.  What we need next is an easy way to transmit the screen specific business rules from each screen to the menu.  The logic and business rules to determine the menu state really fits into each Presenter, but we don't want the Presenter to know about the concrete Menu because we don't want to bind our presentation logic to UI machinery.  We could wrap the Menu in some some sort of abstracted IMenu interface that we could mock while testing the Presenter, but I think there's a better way.  By  and large I think that state-based testing is generally easier than interaction-based testing.  In this case I've opted to use a class called MenuState to configure and transfer screen state from the Presenter to the Menu.  MenuState looks something like this:

 

    public class MenuState
    {
        private Dictionary<CommandNames, string[]> _enabledByRoleCommands
            = new Dictionary<CommandNames, string[]>();
 
        public void Enable(params CommandNames[] names)
        {
            foreach (CommandNames name in names)
            {
                _enabledByRoleCommands.Add(name, new string[0]);
            }
        }
 
        public EnableByRoleExpression Enable(CommandNames name)
        {
            return new EnableByRoleExpression(name, this);
        }
 
        public class EnableByRoleExpression
        {
            private readonly CommandNames _names;
            private readonly MenuState _state;
 
            internal EnableByRoleExpression(CommandNames names, MenuState state)
            {
                _names = names;
                _state = state;
            }
 
            public void ForRoles(params string[] roles)
            {
                _state._enabledByRoleCommands.Add(_names, roles);
            }
        }
 
        public bool IsEnabled(CommandNames name)
        {
            return _enabledByRoleCommands.ContainsKey(name);
        }
 
        public string[] GetRolesFor(CommandNames name)
        {
            if (_enabledByRoleCommands.ContainsKey(name))
            {
                return _enabledByRoleCommands[name];
            }
 
            return null;
        }
    }

Much like the Notification class from the earlier post on validation, the MenuState class helps us to keep the coupling between the menu system and each screen to a minimum.  Also like a Notification, creating a MenuState object from the Presenter makes it relatively easy to unit test the menu state logic in each Presenter.  We'll write interaction tests with mock objects to make sure that the navigation and screen coordination code is correctly applying the result of a call to IPresenter.ConfigureMenu(MenuState) method first.  After that, we can concentrate on just testing the result of a call to IPresenter.ConfigureMenu(MenuState).  The steps to unit test are pretty simple.

  1. Create the screen Presenter class under test
  2. Set any necessary state on the Presenter
  3. Call ConfigureMenu(MenuState)
  4. Lastly, write Assert's that check the expectation of the actual MenuState

On my previous project we created a custom assertion for testing the MenuState calculation that I thought made the test code fairly descriptive.

ICommand you to...

Now, let's talk about how to tell a MenuItem what to do.  Each MenuItem is going to do very different things and interact with different services and modules of the application, but we still want to have a consistent mechanism for attaching actions to MenuItem's.  We could use anonymous delegates (and I'm doing this quite happily in parts of StoryTeller), but that syntax can quickly lead to ugly code.  Instead, let's adopt a Command pattern approach to wrap up each unique action. 

I think one of the fundamental truths of software development is that every codebase wants, nay, demands, an ICommand interface like this one:

 

    /// <summary>
    /// I think I've had some sort of ICommand interface
    /// in almost every codebase I've worked on in the last
    /// 5 years
    /// </summary>
    public interface ICommand
    {
        void Execute();
    }

Using a Command pattern comes with several advantages.  Foremost in my mind is the ability to detach the action into a small concrete unit divorced from a particular screen or UI widget that is easy to test in isolation.  Each of our Command classes should be relatively simple to test.  The ICommand classes are likely manipulating and interacting with various services and other parts of the application.  For easy unit testing, we're probably going to use some sort of Test Double to take the place of these dependencies.  I typically use Constructor Injection to attach the test doubles.

Here's an example command:

 

    public class SaveCommand : ICommand
    {
        private readonly IRepository _repository;
        private readonly IEventPublisher _publisher;
 
        // SaveCommand needs access to the Singleton instance of both
        // IRepository and IEventPublisher.  We'll let StructureMap 
        // deal with wiring up the dependencies
        public SaveCommand(IRepository repository, IEventPublisher publisher)
        {
            _repository = repository;
            _publisher = publisher;
        }
 
        public void Execute()
        {
            // Save whatever it is that we're saving
        }
    }

Inside the unit test harness for SaveCommand I'll simply use RhinoMocks to create mock objects for IRepository and IEventPublisher:

 

    [TestFixture]
    public class SaveCommandTester
    {
        private MockRepository _mocks;
        private IRepository _repository;
        private IEventPublisher _publisher;
        private SaveCommand _command;
 
        /// <summary>
        /// In this method, set up all of the mock objects,
        /// and construct an instance of SaveCommand using
        /// the two mock objects
        /// </summary>
        [SetUp]
        public void SetUp()
        {
            _mocks = new MockRepository();
            _repository = _mocks.CreateMock<IRepository>();
            _publisher = _mocks.CreateMock<IEventPublisher>();
 
 
            _command = new SaveCommand(_repository, _publisher);
        }        
    }

Assuming that you're comfortable with mock objects, SaveCommand is now relatively easy to unit test. Of course we're still left with the problem of how SaveCommand gets the proper instances of IEventPublisher and IRepository in the real application mode.

 

Use StructureMap to Wire Up Commands (and other things)

If you've got yourself a reference to an ICommand object you know exactly what to do to make it work.  Without knowing the slightest thing about its internals, you just call Execute() on the ICommand and get out of the way.  Let's stress part of that again.  The MenuItem and its associated controllers don't need to know anything about the internals of an ICommand object, and they especially don't need to know how to construct and configure an ICommand object.  Looking again at the configuration code, all we do is "tell" each MenuItem controller the name of an ICommand to run. 

            _menuController.MenuItem(saveItem).Executes(CommandNames.Save)

Looking back at our SaveCommand object above, we see that it has a dependency upon both an IEventPublisher and an IRepository interface, but the code above doesn't need to specify these two things.  To make things a little more complicated, both of these interfaces are probably a standin for singleton concrete instances (I use Robert C. Martin's Just Create One pattern for "Managed Singleton's" with StructureMap instead of using traditional Singleton's).  Tracking and attaching dependencies doesn't have to be a terrible chore because we can use tools like StructureMap to help us out.

The first step is to register or configure the proper instances of the underlying services with StructureMap in one of the normal ways like this code below:

 

    public class ServiceRegistry : Registry
    {
        protected override void configure()
        {
            BuildInstancesOf<IEventPublisher>()
                .TheDefaultIsConcreteType<EventPublisher>()
                .AsSingletons();
        }
    }

Now that we've got our services configured we can turn our attention to the ICommand classes.  When we configure the ICommand objects with StructureMap we also need to associate the ICommand Type's with the correct CommandNames (CommandNames is a just a strong typed enumeration, the code is at the very bottom of the post) instance.  I use a separate Registry class for the ICommand's to put the configuration into a common spot and also to create a custom syntax specific to registering ICommand's.

 

    public class CommandRegistry : Registry
    {
        protected override void configure()
        {
            // Wire up the ICommand's
            Command(CommandNames.Save).Is<SaveCommand>();
            Command(CommandNames.Open).Is<OpenCommand>();
        }
    }

For the most part, all I need to do is just say that an instance of CommandNames on the left is the concrete class on the right.  It's important to associate the ICommand classes with an instance of CommandNames because we're going to retrieve ICommand's in the controller classes with this code:

            ICommand command = ObjectFactory.GetNamedInstance<ICommand>(_command.Name);

This Fluent Interface grammar is just a thin veneer over the StructureMap configuration API.  The grammar is implemented in additional members and an inner class of the CommandRegistry:

 

        private RegisterCommandExpression Command(CommandNames name)
        {
            return new RegisterCommandExpression(name, this);
        }
 
        internal class RegisterCommandExpression
        {
            private readonly CommandNames _name;
            private readonly CommandRegistry _registry;
 
            public RegisterCommandExpression(CommandNames name, CommandRegistry registry)
            {
                _name = name;
                _registry = registry;
            }
 
            public void Is<T>()
            {
                // Register the ICommand type with StructureMap
                _registry.AddInstanceOf<ICommand>().UsingConcreteType<T>().WithName(_name.Name);
            }
        }

 

Wait, you might say.  How does the IEventPublisher and IRepository dependencies get into SaveCommand?  We didn't make any kind of definition or configuration between SaveCommand and its services.  The short answer is that we don't have to do anything else because StructureMap supports "auto wiring" of dependencies.  StructureMap knows what SaveCommand needs by its constructor function:

 

        public SaveCommand(IRepository repository, IEventPublisher publisher)
        {
            _repository = repository;
            _publisher = publisher;
        }

If you don't explicitly configure an instance of IRepository/IEventPublisher for SaveCommand StructureMap will happily substitute the default instance of both types into the constructor function of SaveCommand.  While you can always take full control of the dependency chaining, I find it very convenient just to let StructureMap deal with it.

 

* Come on, I'm not the only person that screamed and threw the book across the room when Roland ends up back at the very beginning.  I'm going to swear off fantasy books permanently if Rand doesn't win a clear cut victory in book 12 whenever that comes out.  Almost 20 years worth of waiting better come with a really solid ending.

 

MicroController - One MenuItem at a Time

There's a lot of commonality between the menu items.  Sure, the individual actions and rules are different, but there's a finite set of things we need to do with and to the individual menu items.  You could just use the visual designer to generate one off code for each of the menu items and hard code the menu on/off rules, but that's going to lead to sheer ugliness.  Instead of one off code, let's create a MicroController class for a single MenuItem.

In a stunning fit of creativity I've named this class MenuItemController.  In this design, MenuItemController has just two responsibilities:

  1. Setting up the Click event for the MenuItem
  2. Enabling or disabling the MenuItem

First, let's setup a single MenuItemController and see the code that sets the Click event.

 

    public class MenuItemController
    {
        private readonly MenuItem _item;
        private readonly CommandNames _command;
        private bool _alwaysEnabled = false;
        private List<string> _roles = new List<string>();
 
        public MenuItemController(MenuItem item, CommandNames command)
        {
            _item = item;
            _command = command;
 
            _item.Click += new EventHandler(_item_Click);
        }
 
        private void _item_Click(object sender, EventArgs e)
        {
            ICommand command = ObjectFactory.GetNamedInstance<ICommand>(_command.Name);
            command.Execute();
        }
 
        // Other methods are below...
 
    }

We construct a MenuItemController first with a MenuItem and a CommandNames key.  The constructor simply sets a field for both values then adds an event handler to the MenuItem's Click event.  Inside the _item_Click() event handler the MenuItemController simply fetches the named ICommand from StructureMap (the call to ObjectFactory.GetNamedInstance()) and calls Execute() on the ICommand that comes back.  Great, that's the easy part.  Great that's the easy part.  Now we can tackle the responsibility for enabling or disabling the MenuItem's.

The MenuItemController class uses three sources of information to make the enabled determination.  The first two sources are optional setters on MenuItemController.

 

        public bool AlwaysEnabled
        {
            get { return _alwaysEnabled; }
            set { _alwaysEnabled = value; }
        }
 
        public void AddRoles(string[] roles)
        {
            _roles.AddRange(roles);
        }

In some cases you have MenuItem/Command's that should be available in all states.  The "AlwaysEnabled" flag on MenuItemController will short circuit any other logic and force the MenuItem to be enabled.  The second determination is role-based authorization.  Our MenuItemController class keeps a list of the roles that have access to this action.  If there are no roles defined, we'll assume that the command is accessible to all users.

The third piece of information the MicroController uses to determine menu state is the screen specific rules that are transmitted in the MenuState object created by each Presenter.  The code to enable or disable the internal MenuItem inside of a MenuItemController is below.  The entry point is Enable(MenuState) at the top.

 

        public void Enable(MenuState state)
        {
            _item.Enabled = IsEnabled(state);
        }
 
        public bool IsEnabled(MenuState state)
        {
            if (AlwaysEnabled)
            {
                return true;
            }
 
            if (!state.IsEnabled(_command))
            {
                return false;
            }
 
            return HasRole(state);
        }
 
        public bool HasRole(MenuState state)
        {
            List<string> roles = new List<string>(_roles);
            roles.AddRange(state.GetRolesFor(_command));
 
            return hasRole(roles);
        }
 
        private static bool hasRole(List<string> roles)
        {
            if (roles.Count == 0)
            {
                return true;
            }
 
            IPrincipal principal = Thread.CurrentPrincipal;
            foreach (string role in roles)
            {
                if (principal.IsInRole(role))
                {
                    return true;
                }
            }
 
            return false;
        }

 

Aggregating the MicroController's

By itself, the MicroController classes don't know very much.  The MenuController below aggregates the MenuItemController objects and would ostensibly give you access to a particular MenuItemController upon demand.  In the SetState(MenuState) method it simply iterates through all of the MenuItemController objects and calls each individual MenuItemController.Enable(MenuState) method.

 

    public class MenuController
    {
        private Dictionary<CommandNames, MenuItemController> _items =
            new Dictionary<CommandNames, MenuItemController>();
 
 
        public void SetState(MenuState state)
        {
            foreach (KeyValuePair<CommandNames, MenuItemController> item in _items)
            {
                item.Value.Enable(state);
            }
        }
 
        // Other methods to support the Fluent Interface configuration 
 
    }

 

Building the Fluent Interface

MenuController above also includes the code for the configuration API.  I'm not sure how every one else is building these things, but I typically use "Expression" classes that encapsulate the configuration.  You can recognize these things pretty quickly by looking for a lot of "return this;" calls.  The Expression classes are typically pretty dumb.  All I do with these classes is set properties on some sort of inner object that does the actual work.  The MenuItemExpression class below sets properties on a single MenuItemController as additional methods are called in the configuration.  I tend to use inner classes for the Expression's to get easy access to the private members of the class being configured.  MenuItemExpression is an inner class of MenuController. 

 
        public MenuItemExpression MenuItem(MenuItem item)
        {
            return new MenuItemExpression(this, item);
        }
 
        public class MenuItemExpression
        {
            private readonly MenuController _controller;
            private readonly MenuItem _item;
            private MenuItemController _itemController;
 
            internal MenuItemExpression(MenuController controller, MenuItem item)
            {
                _controller = controller;
                _item = item;
            }
 
            public MenuItemExpression Executes(CommandNames name)
            {
                _itemController = new MenuItemController(_item, name);
                _controller._items.Add(name, _itemController);
 
                return this;
            }
 
            public MenuItemExpression IsAlwaysEnabled()
            {
                _itemController.AlwaysEnabled = true;
                return this;
            }
 
            public MenuItemExpression IsAvailableToRoles(params string[] roles)
            {
                _itemController.AddRoles(roles);
                return this;
            }
        }
 

 

Wrapping it Up

I think MicroController's and Fluent Interface's go together quite well.  The MicroController's do the work, but the Fluent Interface API can make the code so much more readable.  What I'm finding is that it does take a bit of upfront work to get a Fluent Interface put together, but once it's set, it's relatively easy to work with.  There's some Architect Hubris lurking in that statement perhaps.  I suppose I might caution you to utilize a Fluent Interface mostly in situations where you can recoup the upfront investment with lots of reuse or the API pays off when that code changes frequently.

I will write at least one more post on this subject just to present the data binding replacement we're using on my current project (it sounds nuts, but actually, I'm feeling pretty good about that right now).  I wrote about the larval stages in My Crackpot WinForms Idea.

I've received a gratifying number of compliments on this series, but I've consistently heard a common refrain in the negative -- there's no code to download and it's not clear how all the pieces fit together.  To address that problem I'll change my direction a bit, but it means that "Build your own CAB" is going on hiatus for at least a month.  I'm going to concentrate my "stuck on the train" time with getting StoryTeller into a usable state.  I ended up scrapping big pieces of the StoryTeller UI and rebuilding with some of the ideas that I've developed while writing this series.  As soon as it's released, I can use StoryTeller for more complete examples with code that's freely available.

 

Appendix:  CommandNames

I used CommandNames several times in the course of the post but didn't really explain it.  All I've done is create a Java-style strongly typed enumeration for the command names.  StructureMap only understands strings for instance identification within a family of like instances, so CommandNames exposes a Name property.  I suppose that you could just use an enumeration and do ToString() on the keys as appropriate, but I chose this approach for some reason that escapes my mind at the moment.  The code for CommandNames is:

 

    public class CommandNames
    {
        public static CommandNames Open = new CommandNames("Open");
        public static CommandNames Execute = new CommandNames("Execute");
        public static CommandNames Export = new CommandNames("Export");
        public static CommandNames Save = new CommandNames("Save");
 
        private readonly string _name;
 
        private CommandNames(string name)
        {
            _name = name;
        }
 
 
        public string Name
        {
            get { return _name; }
        }
 
 
        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            CommandNames commandNames = obj as CommandNames;
            if (commandNames == null) return false;
            return Equals(_name, commandNames._name);
        }
 
        public override int GetHashCode()
        {
            return _name != null ? _name.GetHashCode() : 0;
        }
    }

 

 

 

* Come on, I'm not the only person that screamed and threw the book across the room when Roland ends up back at the very beginning.  I'm going to swear off fantasy books permanently if Rand doesn't win a clear cut victory in book 12 whenever that comes out.  Almost 20 years worth of waiting better come with a really solid ending.



Comments

Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface - Jeremy D. Miller -- The Shade Tree Developer said:

Pingback from  Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface - Jeremy D. Miller -- The Shade Tree Developer

# July 26, 2007 10:57 AM

Jeremy D. Miller -- The Shade Tree Developer said:

The entire content is now online as a page on my site at: Build your own CAB #14: Managing Menu State

# July 26, 2007 11:05 AM

Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface - Jeremy D. Miller -- The Shade Tree Developer said:

Pingback from  Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface - Jeremy D. Miller -- The Shade Tree Developer

# July 26, 2007 11:06 AM

Colin Ramsay said:

Interesting articles, but:

en.wikipedia.org/.../Apostrophe

;)

# July 26, 2007 1:27 PM

From the software development trenches said:

Time for another weekly roundup of news that focuses on .NET and MS development related content: VS 2008

# July 27, 2007 1:27 AM

Mark A said:

Hi Jeremy,

I've noticed its been awhile since your last post on this subject. any news on when you on finishing this fantastic CAB article set?

# September 25, 2007 6:45 PM

Jeremy D. Miller said:

@Mark:

It's writer's block and motivation.  I'm going to talk to a publisher about the content first before doing anything else.

One way or another, I'll get back to it.

# September 25, 2007 7:53 PM

Jeremy D. Miller -- The Shade Tree Developer said:

After a bit of a hiatus and a fair amount of pestering, I&#39;m back and ready to continue the &quot;Build

# October 21, 2007 9:13 PM

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

# October 21, 2007 9:16 PM

Jeremy D. Miller -- The Shade Tree Developer said:

To everybody that attended one of my talks at DevTeach this week. All of the materials are now online

# November 29, 2007 12:04 PM

nblog said:

Od kilku miesięcy nic tu nie pisałem (oczywiście poza poprzednim nieplanowanym wpisem ). Jak łatwo się

# March 11, 2008 7:07 AM

Ben said:

I have a question about your use of StructureMap to create commands:

ICommand command = ObjectFactory.GetNamedInstance<ICommand>(_command.Name);

command.Execute();

Can this approach work when the command has an argument such as an Id?  If the concrete command class takes the argument as a parameter to its constructor, it doesn't seem like StructureMap can create the command instances.  If instead the command has a setter for the argument, that setter won't be available through the ICommand interface.  

How do you structure your code in this situation?

Thanks,

Ben

# April 24, 2008 4:54 PM

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!

Our Sponsors