Conditional registering a command decorator based on generic type constraints in SimpleInjector
-
05-07-2021 - |
题
How to register a conditional decorator in SimpleInjector
? Here are my definitions:
public interface ICommand { }
public interface ICleanableCommand : ICommand {
void Clean();
}
public interface ICommandHandler<in TCommand>
where TCommand : ICommand {
void Handle(TCommand command);
}
public class CleanableCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
where TCommand : ICleanableCommand {
private readonly ICommandHandler<TCommand> _handler;
public CleanableCommandHandlerDecorator(
ICommandHandler<TCommand> handler) {
_handler = handler;
}
void ICommandHandler<TCommand>.Handle(TCommand command) {
command.Clean();
_handler.Handle(command);
}
}
And I'm trying:
container.RegisterManyForOpenGeneric(
typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies()
);
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CleanableCommandHandlerDecorator<>)
// ,context => context.ImplementationType ???
// I want to register this decorator for commandhandlers
// which their command implements ICleanableCommand
);
解决方案
You can use the RegisterDecorator
overload that takes an DecoratorPredicateContext
to define the condition under which your decorator should be applied. However, since in your case the condition is just the generic type constraint, you don't have to supply a predicate. Simple Injector will automatically ignore the decorator when the given service type is not decoratable, and this includes generic type constraints.
In other words, just register your decorator as follows and it will work correctly:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CleanableCommandHandlerDecorator<>));
其他提示
It seems I can use DecoratorPredicateContext.ServiceType
:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CleanableCommandHandlerDecorator<>),
context => {
var genArg = context.ServiceType.GetGenericArguments()[0];
return typeof(ICleanableCommand).IsAssignableFrom(genArg);
});
不隶属于 StackOverflow