Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

Wicked Cool Jobs

Syndication

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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.


Posted Thu, Jul 26 2007 10:56 AM by Jeremy D. Miller

[Advertisement]

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 wrote 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
on Thu, Jul 26 2007 10:57 AM

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

Jeremy D. Miller -- The Shade Tree Developer wrote My Menu State Management Article from Build a CAB is now online
on Thu, Jul 26 2007 11:05 AM

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

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 wrote 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
on Thu, Jul 26 2007 11:06 AM

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

Colin Ramsay wrote re: 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
on Thu, Jul 26 2007 1:27 PM

Interesting articles, but:

en.wikipedia.org/.../Apostrophe

;)

on Fri, Jul 27 2007 1:27 AM

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

Mark A wrote re: 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
on Tue, Sep 25 2007 6:45 PM

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?

Jeremy D. Miller wrote re: 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
on Tue, Sep 25 2007 7:53 PM

@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.

Jeremy D. Miller -- The Shade Tree Developer wrote Build your own CAB #15 - MicroControllers
on Sun, Oct 21 2007 9:13 PM

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

The Build Your Own CAB Series Table of Contents - Jeremy D. Miller -- The Shade Tree Developer wrote The Build Your Own CAB Series Table of Contents - Jeremy D. Miller -- The Shade Tree Developer
on Sun, Oct 21 2007 9:16 PM

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

Jeremy D. Miller -- The Shade Tree Developer wrote Resources from my DevTeach talks
on Thu, Nov 29 2007 12:04 PM

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

nblog wrote Tfs Spotlight – buduję własny CAB
on Tue, Mar 11 2008 7:07 AM

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

Ben wrote re: 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
on Thu, Apr 24 2008 4:54 PM

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

Dawid Mostert wrote re: 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
on Mon, Nov 24 2008 2:48 AM

How would you control the state of a menu item after the view is shown - i.e. toggle state of a button

AND, how would you control the fact that 1 button might want to invoke different commands based on different contexts?  (i.e. Save button - saves a client in certain contexts or a "product" in other?

Thanks! Great series of articles and would love to see a sample using all these concepts!

Jeremy D. Miller wrote re: 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
on Mon, Nov 24 2008 4:43 PM

@David,

You would go to a different model.  You could bind the menu items to a Command object that has enabled/visible type properties like WPF for the first.

You could recreate the MenuState object each time the menu needs to change (this is workable btw, because I've done it and it worked out well).

For the button doing multiple things, you can "register" for a menu button by passing in a Lambda for what gets called, which gives you the ability to "point" a menu item at a specific presenter.

Dawid Mostert wrote re: 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
on Wed, Nov 26 2008 12:56 AM

Thanks!

So I'm "seeing" the following: Have a "DelegateCommand" class that's got a property that contains the actual delegate that must be executed when the command gets executed.

This new delegate property will be configured  / set in the "ConfigureMenu" method?

For the state, I can hold on to the instance of the MenuState Object and change as necessary in the Presenter and fire off an event so that the menu can be updated?

Do you think this can work?

I've also got a question around your "Command" in this article.  The way that I want to implement my repositories, is to have a method "Save" that takes as parameter the actual object that needs to be persisted. How would this work in your setup?  Would you register the object that needs to be saved with your IoC container and resolve it in the constructor (as you do with the repository)? Or can StructureMap do a lot more than Unity? Please help me with some ideas!

Thanks,

Dawid

Andy wrote re: 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
on Mon, Jun 1 2009 9:01 AM

Hi Jeremy, i have been reading your series and i must say it has been a very good introduction to MVC; something i haven't really looked into before now.

While i was reading this article i noticed that you seem to be dealing with your menu items as the item to be enabled or disabled, however in most applications you end up with two menu items providing certain functionality (think a New button on a toolbar and on the File menu).  This would mean that you have to put the (almost) identical code for controlling them against both items, which seemed a little odd.

I decided to have a go at implementing my own Command-centric version of this, which can be seen on my website: www.stormbase.net/microcontrollers-for-menuitems

If you had the time to have a quick look and see what you think of my version i would be very appreciative.

Thanks

(ps, any chance you can finish off the series please? ;)

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us