<CharlieDigital/> Programming, Politics, and uhh…pineapples

30Sep/09Off

Chain Of Command And Passing Parameters

One of the more useful patterns that I've used quite frequently is a version of Chain of Responsibility that integrates with the Command pattern. In a classic CoR, the idea is that only one component in the chain handles the request and then execution flows out of the chain. In a CoC pattern, the idea is that the execution flows through the entire chain.

I like Shahan Khatchadourian's description of this pattern:

When programming, certain sections of code can sometimes be viewed as a workflow or preset sequence of tasks or commands. This can considered to be the design pattern called Chain of Command...

There are two key problems that this pattern solves that make it immensely useful in everyday programming (it's a bit surprising that dofactory's listing of CoR lists the frequency of use as a 2/5).

The first problem that it solves is extensibility. By implementing the chain as a list of abstract types (Command or Validator or whatever), using reflection (one way or another), you can build a list of concrete commands, giving each element in the chain a chance of working on the input request. One example of how I use this is to implement validation where I might have an abstract base class called Validator. To build the chain of validators, one very quick and easy solution is to reflect on the assembly and simply find all of the classes which implement Validator (additional complexity can be added as necessary, such as supporting validators in external assemblies or different groupings of validators).

The second (related) problem that it solves is excessively large blocks of if statements. In a validation example, you can imagine that if it were written in-line, each validation rule would essentially map to an if statement in a large block. In a way, it's a very useful pattern for exchanging a tiny bit of performance and memory for more modular organization of logic. Without the CoC pattern, adding a new validation rule would mean adding another if block - yuck! Using CoC with reflection, we can simply add another class which inherits Validator to our project and count on the component building the chain to find our class and add it to the chain.

Here is a very simple, barebones implementation:

/// <summary>
/// A simple command chain factory that doesn't do wiring.
/// </summary>
public static class SimpleCommandChainFactory
{
    /// <summary>
    /// Creates a simple list of commands to execute using reflection.
    /// </summary>
    public static List<Command> Create()
    {
        var commands = new List<Command>();
 

        Type[] types = Assembly.GetExecutingAssembly().GetTypes();
        Type commandType = typeof (Command);

        foreach (Type type in types)
        {
            if (!type.IsSubclassOf(commandType))
            {
                continue;
            }

            MemberInitExpression init = Expression.MemberInit(
                Expression.New(type), new MemberBinding[0]);

            Command command = Expression.Lambda<Func<Command>>(init)
                .Compile().Invoke();

            commands.Add(command);
        }

        commands = commands.OrderBy(c => c.Priority).ToList();

        return commands;
    }
}

The code checks to see if a type if a sub-type of Command and, if so, creates an instance and puts it on the chain. The commands could then be executed like so:

internal class Program
{
    private static void Main(string[] args)
    {
        List<Command> commands = SimpleCommandChainFactory.Create();
 

        // Execute each command.
        foreach(Command command in commands)
        {
            command.Execute();
        }
    }
}

In this case, I'm not passing in data or checking for stop conditions (which might be useful in a validation scenario where the first failure stops processing). To do so, you could simply pass in a single instance of some context class to each command when executing and check to see if the stop condition is true after the execute call (and break out of the for-loop).

While this pattern is immensely useful any time you find a big if or switch block that's particularly volatile, one problem that I've found with this pattern is passing parameters between two elements in the chain. Ideally, no element in the chain should have a dependency on another element in the chain. We want to decouple each of the elements to make it easier to build the chain dynamically. What this means is that no element should directly set values on another element in the chain. In essensce, to emulate the functionality of DependencyObject and DependencyProperty that we find in WF and WPF. (Why not just use WF then? Complexity and performance.)

At least two solutions come to mind. The first is to pass a context with a dictionary through each element of the chain. This would allow each element to place an output value into the dictionary and downstream components to pull these values out. The downside of this approach is that unless you force everything into one value type (i.e. serialize to an XML string?), you can't really pass strongly typed data and now you're keyed by strings (or whatever value type) which you need to have know about in order to retrieve the value.

A second approach would be to leverage DependencyObject and DependencyProperty. While this sounds good in principle, it requires a mess of code to accomplish in your own code with your own objects. Not only that, it seems to be overkill since many times, you don't need the full capabilities of the dependency system - you just want to pass a value downstream in a nice, strongly typed manner.

(There is a third approach using thread local storage, but this is probably an even worse option than the first since it wouldn't be very accessible to most developers and it doesn't really address the issue at hand.)

In the past, I've relied on the dictionary based approach. While it wasn't ideal, it was the simplest solution that got the job done. Deep down, I always hated this approach because I didn't like having to know the keys and having to know how to cast the results retrieved from the dictionary. However, I recently came up with a much better solution to this issue: dynamically wired events.

We introduce two attribute classes which we can use to identify our event publishers and event subscribers. For brevity, I'll only show the publisher attribute (they are pretty much the same in this implementation):

/// <summary>
/// Attribute used to identify event publishers.
/// </summary>
[AttributeUsage(AttributeTargets.Event)]
public class EventPublisherAttribute : Attribute
{
    private readonly string _eventName;
 

    /// <summary>
    /// Initializes a new instance of the <see cref="EventPublisherAttribute"/> class.
    /// </summary>
    /// <param name="eventName">Name of the event.</param>
    public EventPublisherAttribute(string eventName)
    {
        _eventName = eventName;
    }

    /// <summary>
    /// Gets the name of the event.
    /// </summary>
    /// <value>The name of the event.</value>
    public string EventName
    {
        get { return _eventName; }
    }
}

The only difference between the two in this case is the AttributeUsageAttribute. In the case of the subscriber, we want it to apply to methods, not events. Next, we need to apply these attributes to our concrete command types that we're going to chain. For this example, let's say that the first item in the chain generates a GUID key that the rest of the items in the chain also need to use:

/// <summary>
/// Generates a GUID that may be needed by the rest of the chain.
/// </summary>
public class GenerateKeyCommand : Command
{
    /// <summary>
    /// Raised when a key is generated;
    /// </summary>
    [EventPublisher(EventNames.KeyGenerated)]
    public event EventHandler<EventArgs<Guid>> KeyGenerated;
 

    /// <summary>
    /// Executes this instance.
    /// </summary>
    public override void Execute()
    {
        Guid key = Guid.NewGuid();

        Console.Out.WriteLine("From GenerateKeyCommand: {0}", key);

        OnKeyGenerated(key);
    }

    /// <summary>
    /// Gets the priority.  A lower value indicates higher priority.
    /// </summary>
    /// <value>The priority.</value>
    public override int Priority
    {
        get { return 1; }
    }

    /// <summary>
    /// Raises the key generated event.
    /// </summary>
    /// <param name="key">The key.</param>
    private void OnKeyGenerated(Guid key)
    {
        if(KeyGenerated != null)
        {
            KeyGenerated(this, new EventArgs<Guid>(key));
        }
    }
}

As you can see, it's pretty standard stuff, with the exception of the additional attribute on the event. Downstream, we want to handle these events in other commands:

/// <summary>
/// Simple command just for demonstration purposes.
/// </summary>
public class DoSomethingWithKeyCommand : Command
{
    private Guid _key;
 

    /// <summary>
    /// Executes this instance.
    /// </summary>
    public override void Execute()
    {
        Console.Out.WriteLine("From DoSomethingWithKeyCommand: {0}", _key);
    }

    /// <summary>
    /// Gets the priority.  A lower value indicates higher priority.
    /// </summary>
    /// <value>The priority.</value>
    public override int Priority
    {
        get { return 100; }
    }

    [EventSubscriber(EventNames.KeyGenerated)]
    private void HandleKeyGenerated(object sender, EventArgs<Guid> e)
    {
        _key = e.Data;
    }
}

You can see that in the event handler method, we just grab the value from the event arguments and set it on a local variable for use when Execute() is called.

Now the trick is to wire these events up using reflection to avoid creating the direct dependency between the different elements in the chain. Spring.NET offers one way to do this using declarative events, however, it should be noted that it only works with singleton objects (this bit me in the butt until I figured it out). Depending on the nature of your elements in the chain, that may or may not be sufficient for you. If you need new instances every time, then we can accomplish this ourselves using a bit of reflection.

(Note that none of the code that follows has been optimized; there are a few caching opportunities to take advantage of to cut down on some of the reflection calls.)

The first step is to modify the factory method:

/// <summary>
/// Creates a command chain using reflection.
/// </summary>
/// <returns></returns>
public static List<Command> Create()
{
    List<Command> commands = new List<Command>();
 

    Type[] types = Assembly.GetExecutingAssembly().GetTypes();
    Type commandType = typeof (Command);

    Dictionary<string, List<EventCoupling>> eventSources
        = new Dictionary<string, List<EventCoupling>>();

    Dictionary<string, List<MethodCoupling>> eventTargets
        = new Dictionary<string, List<MethodCoupling>>();

    foreach(Type type in types)
    {
        if(!type.IsSubclassOf(commandType))
        {
            continue;
        }

        MemberInitExpression init = Expression.MemberInit(
            Expression.New(type), new MemberBinding[0]);

        Command command = Expression.Lambda<Func<Command>>(init)
            .Compile().Invoke();

        commands.Add(command);

        BuildHandlerCache(command, eventTargets, 
            type.GetMethods(_methodFlags));

        // Parse the events.
        EventInfo[] events = type.GetEvents(
            BindingFlags.Public | BindingFlags.Instance);

        if(events.Length == 0)
        {
            continue; 
        }

        BuildEventCache(command, eventSources, events);
    }

    WireEvents(eventSources, eventTargets);

    commands = commands.OrderBy(c => c.Priority).ToList();

    return commands;
}

We create two caches as we iterate through the types to hold the events and handler methods that we encounter as we iterate the types and as a final step, we wire the events together from the caches. The cache building logic is fairly straightforward:

/// <summary>
/// Builds the handler cache.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="eventTargets">The event targets.</param>
/// <param name="methods">The methods.</param>
private static void BuildHandlerCache(
    Command command, 
    IDictionary<string, List<MethodCoupling>> eventTargets, 
    IEnumerable<MethodInfo> methods)
{
    foreach(MethodInfo method in methods)
    {
        EventSubscriberAttribute[] subscriberAttributes =
            (EventSubscriberAttribute[])
            method.GetCustomAttributes(
                typeof(EventSubscriberAttribute), false);
 

        if (subscriberAttributes.Length == 0)
        {
            continue;
        }

        foreach(EventSubscriberAttribute attribute in subscriberAttributes)
        {
            if(!eventTargets.ContainsKey(attribute.EventName))
            {
                eventTargets[attribute.EventName] = new List<MethodCoupling>();
            }

            eventTargets[attribute.EventName].Add(
                new MethodCoupling(method, command));
        }
    }
}

/// <summary>
/// Builds the event caches.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="eventSources">The event sources.</param>
/// <param name="events">The events.</param>
private static void BuildEventCache(
    Command command,
    IDictionary<string, List<EventCoupling>> eventSources,  
    IEnumerable<EventInfo> events)
{
    foreach(EventInfo eventInfo in events)
    {
        EventPublisherAttribute[] publisherAttributes =
            (EventPublisherAttribute[])
            eventInfo.GetCustomAttributes(
                typeof (EventPublisherAttribute), false);

        if(publisherAttributes.Length == 0)
        {
            continue;
        }

        foreach (EventPublisherAttribute attribute in publisherAttributes)
        {
            if(!eventSources.ContainsKey(attribute.EventName))
            {
                eventSources[attribute.EventName] = new List<EventCoupling>();
            }

            eventSources[attribute.EventName].Add(
                new EventCoupling(eventInfo, command));
        }
    }
}

The gist of it is that we want to iterate through the events and the methods, find the ones with the attributes, map them to instances of commands, and throw them into a dictionary. As you can see, the dictionary values are generic lists on both sides; this means that a single event can fire multiple event names and a single handler method can handle multiple events (as long as the method input types are the same). This may or may not be useful in any given scenario, but it's easy enough to rewrite this to make it a bit simpler if it's not required.

Finally, we need to wire the events together in the chain after it's created:

private static void WireEvents(
    Dictionary<string, List<EventCoupling>> eventSources,
    Dictionary<string, List<MethodCoupling>> eventTargets)
{
    foreach(string key in eventSources.Keys)
    {
        if(!eventTargets.ContainsKey(key))
        {
            continue;
        }
 

        List<MethodCoupling> targets = eventTargets[key];
        List<EventCoupling> sources = eventSources[key];

        foreach(EventCoupling source in sources)
        {
            foreach(MethodCoupling target in targets)
            {
                Delegate d = Delegate.CreateDelegate(
                    source.Event.EventHandlerType,
                    target.Command,
                    target.Method);

                source.Event.AddEventHandler(source.Command, d);
            }
        }
    }
}

It's as simple as that: we loop through each event (publishers) and see if there is a list of methods (subscribers) to handle it in the chain. If so, we add a delegate as a handler to the event. In my sample project, I created three simple command types to demonstrate; here's the output when I run my program:

You can see, once the key is generated in the first command, the value is available in the downstream commands using the events. The nice thing is that we can add more steps to our logic without much extra work. This is particularly handy for something like implementing a chain of validation rules as it means that you don't end up writing a big if if block. But even in general usage, this pattern is useful for breaking out a large method into smaller, more modular pieces in a much more extensible manner.

One neat thing is that it allows you to not only wire events downstream, but also upstream as well. This means that if an element in your chain triggers an event, code in a previous even is executed if there is a handler wired for it.

In a more complete implementation, you may consider using Spring.NET or Unity or simply .NET configuration to statically identify the elements of the chain (instead of the basic reflection I've used). You may also consider more error handling logic šŸ˜‰ and passing an instance of a context through each element in the chain.

The full sample project is available here: ChainOfCommandSample.zip (11.21 KB)

Posted by Charles Chen

Filed under: .Net, Dev Comments Off
Comments (2) Trackbacks (0)
  1. What you describe seems very close to the Pipe & Filters pattern. How do you feel the two patterns compare?

    -mike

  2. Mike,

    As far as I can tell, Pipe and Filters is a higher level abstraction (in most contexts, it’s used in discussion of message handling) than Chain of {Something}. I think the best way to describe the relationship is that Chain of {Something} can be used to _implement_ Pipe and Filters.

    But the gist of the idea is the same: break up logic into small, more modular, more pluggable units.


Trackbacks are disabled.