4

ICommandHandler<T>対応するタイプを使用して、タイプDeadlockRetryCommandHandlerDecorator<T>に基づいてすべてを飾る必要があります

この解決策を試しましたが、残念ながら機能しません。

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

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

ジェネリックデコレータ()を登録して、すべてのジェネリック実装DeadlockRetryCommandHandlerDecorator<T>をラップするにはどうすればよいですか?ICommandHandler<T>

4

2 に答える 2

1

Windsorは常にオープンジェネリックよりもモード固有のコンポーネントを優先するため、現在これはOOTBではサポートされていません。

ただし、これは非常に簡単に機能させることができ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でそのようなシナリオを実現するための推奨される方法は、インターセプターを使用することです。

于 2012-09-29T00:49:26.837 に答える
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);
}
于 2015-11-22T17:02:32.740 に答える