如何使用Castle Windsor注册通用装饰器?

我需要使用相应的DeadlockRetryCommandHandlerDecorator类型基于ICommandHandler类型来装饰所有类型

我试过这个解决方案,但遗憾的是它不起作用。

 container.Register( Component.For(typeof(ICommandHandler)) .ImplementedBy(typeof(DeadlockRetryCommandHandlerDecorator))); container.Register( AllTypes.FromThisAssembly() .BasedOn(typeof(ICommandHandler)) .WithService.Base()); 

如何注册通用装饰器( DeadlockRetryCommandHandlerDecorator )来包装所有通用ICommandHandler实现?

目前这不支持OOTB,因为Windsor总是倾向于特定于模式的组件而不是开放式generics。

你可以使用ISubDependencyResolver轻松地完成这项工作。 下面的代码假设您为装饰器"DeadlockRetryCommandHandlerDecorator"命名组件

 public class CommandHandlerResolver : ISubDependencyResolver { private readonly IKernel kernel; public FooResolver(IKernel kernel) { this.kernel = kernel; } public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { return (dependency.TargetType.IsGenericType && dependency.TargetType.GetGenericTypeDefinition() == typeof (ICommandHandler<>)) && (model.Implementation.IsGenericType == false || model.Implementation.GetGenericTypeDefinition() != typeof (DeadlockRetryCommandHandlerDecorator<>)); } public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { return kernel.Resolve("DeadlockRetryCommandHandlerDecorator", dependency.TargetItemType); } } 

然而,使用拦截器来实现与Windsor一样的场景的推荐方法。

我遇到过同样的问题。 我设法通过将每种类型明确注册为更具体的类型来解决它。 对我来说,这个解决方案比使用子依赖解析器更清晰

 var commandTypes = businessAssembly.GetTypes() .Where(t => !t.IsInterface && typeof(ICommand).IsAssignableFrom(t)); foreach(var commandType in commandTypes) { var handlerInterface = typeof(ICommandHandler<>).MakeGenericType(new[] { commandType }); var transactionalHandler = typeof(DeadlockRetryCommandHandlerDecorator<>).MakeGenericType(new[] { commandType }); container.Register(Component.For(handlerInterface) .ImplementedBy(transactionalHandler) .LifeStyle.PerWebRequest); }