регистрация открытых универсальных декораторов для типизированных реализаций в замке виндзор

Пытаясь заставить Виндзор обернуть реализацию случайным числом декораторов, я наткнулся на следующее:

у меня есть 3 декоратора и реализация, использующая один и тот же интерфейс.

если вы запустите этот код, Виндзор решаетicommandhandler<stringcommand> какimplementation, что, насколько я могу судить, является ожидаемым поведением, потому что типизированная реализация не может быть зарегистрирована с открытыми типизированными декораторами.

Однако, если вы раскомментируете строкуcontainer.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());все три декоратора будут использованы для разрешенияimplementation, который является желаемым результатом (вроде:).

class Program
{
    static void Main(string[] args)
    {
        var container = new WindsorContainer();

        container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator1<>)));
        container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator2<>)));
        container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator3<>)));

        //uncomment the line below and watch the magic happen
        //container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());
        container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<implementation>());

        var stringCommandHandler = container.Resolve<ICommandHandler<stringCommand>>();
        var command = new stringCommand();
        stringCommandHandler.Handle(command);

        Console.WriteLine(command.s);
        Console.ReadKey();
    }
}

public interface ICommandHandler<T>
{
    void Handle(T t);
}

public class stringCommand
{
    public string s { get; set; }
}

public abstract class Decorator<T> : ICommandHandler<T>
{
    public abstract void Handle(T t);
};

public class Decorator1<T> : Decorator<T>
    where T : stringCommand
{
    private ICommandHandler<T> _handler;
    public Decorator1(ICommandHandler<T> handler)
    {
        _handler = handler;
    }

    public override void Handle(T t)
    {
        t.s += "Decorator1;";
        _handler.Handle(t);
    }
}

public class Decorator2<T> : Decorator<T>
    where T : stringCommand
{
    private ICommandHandler<T> _handler;
    public Decorator2(ICommandHandler<T> handler)
    {
        _handler = handler;
    }

    public override void Handle(T t)
    {
        t.s += "Decorator2;";
        _handler.Handle(t);
    }
}
public class Decorator3<T> : Decorator<T>
    where T : stringCommand
{
    private ICommandHandler<T> _handler;
    public Decorator3(ICommandHandler<T> handler)
    {
        _handler = handler;
    }

    public override void Handle(T t)
    {
        t.s += "Decorator3;";
        _handler.Handle(t);
    }
}

public class implementation : ICommandHandler<stringCommand>
{
    public void Handle(stringCommand t)
    {
        t.s += "implementation;";
    }
}

Почему именно это происходит, это особенность Виндзора, о которой я не знаю? Есть ли другой способ достичь того же эффекта? (не прибегая к размышлениям)

Ответы на вопрос(1)

Ваш ответ на вопрос