如何在SimpleInjector
中注册条件装饰器?以下是我的定义:
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);
}
}
我正在努力:
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
);
答案 0 :(得分:5)
您可以使用RegisterDecorator
重载来DecoratorPredicateContext
来定义应用装饰器的条件。但是,因为在您的情况下,条件只是泛型类型约束,所以您不必提供谓词。当给定的服务类型不可解析时,Simple Injector将自动忽略装饰器,这包括泛型类型约束。
换句话说,只需按照以下方式注册装饰器,它就能正常工作:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CleanableCommandHandlerDecorator<>));
答案 1 :(得分:2)
我似乎可以使用 DecoratorPredicateContext.ServiceType
:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CleanableCommandHandlerDecorator<>),
context => {
var genArg = context.ServiceType.GetGenericArguments()[0];
return typeof(ICleanableCommand).IsAssignableFrom(genArg);
});