2012-09-28 107 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); 
} 
相關問題