About Me

While at The Day Job, I noticed we had some services that all shared the same cross-cutting concerns. In particular, validating a request object. You may think of some other ones, like logging, auditing, standard error-handling, etc. Due to other architectural concerns of our project, it made sense to decorate a common interface we had as a way to achieve the validation. First, here’s our generic interface that we want to decorate:

Simply put, it just says given a request object, I’ll return a standard response object. To show it “in action”, here’s a sample implementation. Note that the interface has already assumed at this point that the request object has been validated.

Pretty standard stuff, nothing special. Just a domain service that takes in a request, performs some domain operations, then saves changes to a repository.

Now for our decorator. If you’re unfamiliar with the decorator pattern, here’s the simple version – a decorator is a class that implements an interface, and also consumes an instance of that interface in it’s constructor. This allows you to “intercept” any calls against the passed-in instance to add extra behavior, while wrapping the consumed instance. Your consuming application doesn’t have to change it’s code at all – your IoC container will do the magic for you. You just code against the interface like normal, and everything is happy. You can even have multiple decorators (each one consuming another!).

Easy peasy! It takes in IService<A,B>, and implements it as well. So, again – the magic needs to be handled by our IoC Container, in our case, StructureMap. StructureMap already has some great support for auto-registering open generic types with the “ConnectImplementationsToTypesClosing” function, and decorator support with the “EnrichWith” function. However, combining the two can be prolematic, as EnrichWith except your type, if generic, to be a closed generic type (meaning you know the type parameters explicitly). Obviously, we don’t know that – well, we could, but that’d mean every time we added a new request/response pairing for our IServiceOperation, we’d have to modify our container. This would lead to a lot of copy/pasted code in our container, be something everyone would forget to do, and another spot to be affected when renaming objects. Not exactly ideal.

It took quite a bit of digging, even posted the question to StackOverflow, but did not get a response. Eventually, I was able to find a solution – a custom IRegistrationConvention! If you’re not familiar with this (as I wasn’t), this is a hook StructureMap provides. By implementing this interface from Structuremap, you’ll get a hook in the form of a function that is called for every type StructureMap finds when starting up (depending on what assemblies you tell it to scan). From here, I was able to inspect each type, and see what interfaces it implemented. If the implemented interface was IServiceOperation, then through reflection I could get what two types (the response and request) were used to close the implementation, then tell StructureMap that for that closed type, to return my decorator using those same two types (with Activator.CreateInstance).

Here’s my final StructureMap code, showing it all hooked together. I hope this helps other people!

publicclass StructureMapServiceScanner : Registry
{
public StructureMapServiceScanner()
{
Scan(scanner =>
{
//Tells StructureMap to scan all types in the assmebly where the interface is defined
scanner.AssemblyContainingType(typeof (IServiceOperation<,>));
//Tells StructureMap that for all requests of IServiceOperation to automatically return//the concrete type that closes the interface with the same as the requested parameters
scanner.ConnectImplementationsToTypesClosing(typeof (IServiceOperation<,>));
//And finally, we add our new registration convention
scanner.Convention<ServiceRegistrationConvention>());
});
}
}