2012-09-28 48 views
4

我需要装饰上使用相应的DeadlockRetryCommandHandlerDecorator<T>如何使用Castle Windsor注册通用装饰器?

我试过这个解决方案ICommandHandler<T>所有类型为主,但遗憾的是它不工作。

container.Register(
    Component.For(typeof(ICommandHandler<>)) 
    .ImplementedBy(typeof(DeadlockRetryCommandHandlerDecorator<>))); 

container.Register(
    AllTypes.FromThisAssembly() 
     .BasedOn(typeof(ICommandHandler<>)) 
     .WithService.Base()); 

我如何注册一个通用的装饰(DeadlockRetryCommandHandlerDecorator<T>)来包装所有一般性ICommandHandler<T>实现?

回答

1

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

虽然你可以很容易地与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); 
    } 
} 

建议实现这样的与温莎场景方式不过是使用拦截器。

+2

我该如何实现ISubDependencyResolver? – oguzh4n

0

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

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); 
} 
相关问题