Wine decorator
I'm trying to get a generic decorator around several non-generic handler commands. Is this possible without registering each handler separately?
Current Windsor command handler registration (working):
container.Register(Classes.FromAssemblyNamed(namespaceName)
.BasedOn(typeof(IDomainCommandHandler<>))
.WithService.AllInterfaces()
.LifestyleTransient());
Simple decorator:
public class Decorator<T> : IDomainCommandHandler<T> where T : IDomainCommand
{
private readonly IDomainCommandHandler<T> _decoratedCommandHandler;
public Decorator(IDomainCommandHandler<T> decoratedCommandHandler)
{
_decoratedCommandHandler = decoratedCommandHandler;
}
public void Handle(T command)
{
_decoratedCommandHandler.Handle(command);
}
}
Simple command / handler:
public class MyCommand : IDomainCommand
{
}
public class MyCommandHandler : IDomainCommandHandler<MyCommand>
{
public void Handle(MyCommand command)
{
}
}
I tried the following registration but the decorator is not being applied.
container.Register(Component.For(typeof(IDomainCommandHandler<>))
.ImplementedBy(typeof(Decorator<>))
.LifestyleTransient());
Suggestions?
EDIT: Another limitation that I forgot to mention initially is that some of these command handlers are used by two different applications. You need a decorator and not another.
source to share
You are probably getting "a dependency loop was encountered while trying to resolve a component ...", right? This is because the decorator ctor contains an IDomainCommandHandler <T>
public Decorator(IDomainCommandHandler<T> decoratedCommandHandler)
and when you try to resolve IDomainCommandHandler <T> inside Decorator it blows up.
The permission chain looks like this here:
-
Give me an IDomainCommandHandler
//MyCommand type could be provided through a TypeFactoryComponentSelector var myDecoratedCommandHandler = container.Resolve<IDomainCommandHandler<MyCommand>>();
-
The lock resolves Decorator <>, but then it resolves its own dependency
IDomainCommandHandler<T> decoratedCommandHandler
And since you've already provided a T, which in this case is MyCommand, Castle goes to resolve the Decorator again, and when it does it twice it gives up. The only registration for IDomainCommandHandler is Decorator <T>. This issue is discussed here.
You can achieve "decorator" properties with DynamicProxy .
The decorator pattern is usually used when you want to extend an implementation. This is true? Can you give an example of a possible addition to your DomainCommandHandlers? Are you trying to implement Cross Cutting Concerns?
The only possible answer that sticks to your style is implementing a typed Factory object using ITypedFactoryComponentSelector or FactoryMethod and using a resolution stack. Then you can recursively traverse the container permission permission stack and return MyDomainCommandler if you have a Decorator on the stack. It is like a decision chain binding that says "Now I see that you are already resolving the Decorators dependencies, so please enable non Decorator again."
source to share