Went off on an interesting tangent today after reading this article on command handler decoration. I wanted to see if I could implement the pattern using Unity instead of Si
I hope I understand the problem correctly and I was curious to try and get this to work and I'm by no means an expert on Unity but I was thinking of a solution that is a little easier to implement and would also be easier to do with a different container. It would seem like the only way to support the open generic as well as the other types is to have 2 separate containers (1 for the open generic) and one for your command handlers, this might not be the best way but it worked with Unity and I'm assuming will also be easier with others.
So I came up with this:
I created the containers as follows (you can use your convention approach still im sure for the handler container)
var container = new UnityContainer();
var container2 = new UnityContainer();
container2.RegisterType(typeof(ICommandHandler),
typeof(QueryCommandHandler));
container.RegisterInstance("Handlers", container2);
container.RegisterInstance(container);
container.RegisterType(typeof(ICommandHandler<>),
typeof(DecoratedHandler<>));
You see container 2 containing the Handlers as a named instance.
Then I just created a Generic base decorator class as per the requirement of the pattern:
public class DecoratorCommandHandler
: ICommandHandler
{
private ICommandHandler inner;
public DecoratorCommandHandler(
ICommandHandler inner)
{
this.inner = inner;
}
public virtual void Handle(TCommand command)
{
this.inner.Handle(command);
}
}
Second I created another Generic Handler that would wrap all the Decorations you want to do for your solution, here you will add decorating for TryCatch/Caching/Transactions or whatever else you want to apply to each command handler:
public class DecoratedHandler
: DecoratorCommandHandler
{
public DecoratedHandler(UnityContainer container)
: base(BuildInner(container))
{
}
private static ICommandHandler BuildInner(
UnityContainer container)
{
var handlerContainer =
container.Resolve("Handlers");
var commandHandler =
handlerContainer.Resolve>();
return new TryCatchCommandHandler(commandHandler);
}
}
You will notice that the first inner resolves the actual command handler as per the one you requested like QueryCommandHandler, UpdateCommandHandler, ExecuteCommandHandler or whatever one dealing with specifics. And then gets wrapped with all the decorators you want common to all of them.
Then I was able to resolve the correct handler, decorated in the correct way:
ICommandHandler handler =
container.Resolve>();
var cmd = new QueryCommand();
handler.Handle(cmd);
Hope this helps