如何注册使用温莎城堡通用的设计师吗?如何注册使用温莎城堡通用的设计师吗?(How can I reg

2019-05-12 03:21发布

我需要装饰全部基于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>实现?

Answer 1:

目前,这是不支持开箱即用的,由于这样的事实,温莎总是在一个开放式的通用模式,有利于特定组件。

你可以得到与工作很容易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);
    }
}

然而实现这样的与温莎场景的推荐方法是使用拦截器。



Answer 2:

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

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);
}


文章来源: How can I register a generic decorator using Castle Windsor?