|Well, I've been all over the place on how to implement flow-based programming in C#. I've discovered several ways of doing it, a couple of which you can read about in my previous blog entry.
What I've settled on is an approach inspired by the
System.Runtime.Remoting.Channels namespace. This namespace uses the concept of sinks and sink chains. You have a chain of objects that process messages. Well, that's very much like what I'm trying to accomplish with my MIDI toolkit!
So I've created a set of sink interfaces, one for each message type. Classes that implement these interfaces can be placed in a chain of objects which process MIDI messages. For example, take the
IChannelSink from the MIDI toolkit:
public interface IChannelSink
void ProcessMessage(ChannelMessage message);
This represents the basic functionality for an object to serve in a sink chain. An example of chaining objects together:
InputDevice inDevice = new InputDevice(0);
UserSink userSink = new UserSink(); ChannelStopper stopper = new ChannelStopper();
OutputDevice outDevice = new OutputDevice(0);
inDevice.ChannelSink = userSink;
userSink.NextChannelSink = stopper;
stopper.NextChannelSink = outDevice;
The chain begins with an
InputDevice class. This class doesn't actually implement the
IChannelSink interface since it is the first link in the chain. It simply receives messages and does not process them.
The second object in the chain is a hypothetical user defined sink. This sink processes messages in a user defined way.
ChannelStopper sink keeps track of any sounding notes. When the flow of messages stop, the stopper's
AllSoundsOff method can be called to stop any sounding notes so that they are not left hanging.
And finally, the output device serves as the last link in the chain. It simply sends the messages to an output device.
So after much consideration, I think I've settled on the way in which I want to implement flow-based programming in C#.
BTW, this implementation looks a lot like the Chain of Responsibility design pattern. The main difference is that this approach is about processing messages rather than handling requests, but they are very similar.