Following on from my last post about Actions, Predicates, and Funcs; I want to provide an example of one place that I've seen a framework successfully use an Action as in an API. Recently, I've been doing some work with NServiceBus (NSB). NSB gives a nice terse way to Send or Publish a new message. It looks like this:
This code uses an Action<T> underneath to create a new instance of the type that is going to be sent or published. What is extra cool about this is that NSB allows you to define values for properties of an instance that it will dynamically generate. Like the example above, this allows NSB to give the impression that it can assign values directory to interface properties!
So, how can we allow users of our API to define properties, but keep hold of the specifics about how we create an object?
Action<T> as Builder
Like NSB, we can take in an Action<T> and allow the user of the API to build the object they desire. To show the specifics of how to do this, I'll complete a non-production version of what NSB does. So, first we need to define the IBus interface:
And this is a simple implementation for IBus:
A bit of explanation
So, it turns out that the code is quite simple for a pretty cool API feature. The implementation of IBus only needs to understand the type of the message, then can create a blank instance, and pass the instance to the action for building. At this point, the action implementation (defined in the method call to IBus.Publish<T>) takes over and fills in all the properties. This works because T has to be an IMessage (which means it must be a reference type). Nice. Using this type of technique would also allow the framework code to make a default instance (with some properties set) and let these values to be changed during the action implementation.
More to come...