Лучший способ настроить Виндзорский замок для массива декораторов

У меня в интерфейсе проекта

public interface IUpdater
{
    void Update();
}

и некоторые реализации UpdaterA, UpdaterB, UpdaterC У меня также есть декоратор DecoratorUpdater. Все эти классы реализуют интерфейс IUpdater, и мне нужно настроить Windsor Castle для использования в качестве реализаций, украшенных массивом, в классе UpdaterService

Мое решение следующее, но это не так просто, как может быть (в настоящее время у меня есть 7 обновителей и 2 декоратора)

        // decorators
        Container.Register(
            Component.For<IUpdater, DecoratorUpdater>().LifestylePerWebRequest().Named("DecoratorUpdaterA").DependsOn(Dependency.OnComponent("underlyingUpdater", "NamedUpdaterA")),
            Component.For<IUpdater, DecoratorUpdater>().LifestylePerWebRequest().Named("DecoratorUpdaterB").DependsOn(Dependency.OnComponent("underlyingUpdater", "NamedUpdaterB")),
            Component.For<IUpdater, DecoratorUpdater>().LifestylePerWebRequest().Named("DecoratorUpdaterC").DependsOn(Dependency.OnComponent("underlyingUpdater", "NamedUpdaterC")));

        // updaters
        Container.Register(
            Component.For<IUpdater, UpdaterA>().LifestylePerWebRequest().Named("NamedUpdaterA"),
            Component.For<IUpdater, UpdaterB>().LifestylePerWebRequest().Named("NamedUpdaterB"),
            Component.For<IUpdater, UpdaterC>().LifestylePerWebRequest().Named("NamedUpdaterC"));

        // usages
        Container.Register(Component.For<UpdaterService>().ServiceOverrides(new
        {
            updaters = new[] 
            { 
                "DecoratedUpdaterA", 
                "DecoratedUpdaterB", 
                "DecoratedUpdaterC", 
            }
        }));

Есть ли лучший способ настроить Виндзорский замок?


person Rudis    schedule 14.10.2013    source источник


Ответы (3)


Хорошо, лучшего решения, чем мое, нет.

person Rudis    schedule 16.10.2013

Другое, немного более короткое решение

        Container.Register(
            Component.For<IUpdater>().ImplementedBy<DecoratorUpdater>().DependsOn(Dependency.OnComponent(typeof(IUpdater), typeof(UpdaterA))).Named("DecoratedUpdaterA").LifestylePerWebRequest(),
            Component.For<UpdaterA>().ImplementedBy<UpdaterA>().LifestylePerWebRequest(),
            Component.For<IUpdater>().ImplementedBy<DecoratorUpdater>().DependsOn(Dependency.OnComponent(typeof(IUpdater), typeof(UpdaterB))).Named("DecoratedUpdaterB").LifestylePerWebRequest(),
            Component.For<UpdaterB>().ImplementedBy<UpdaterB>().LifestylePerWebRequest(),
            Component.For<IUpdater>().ImplementedBy<DecoratorUpdater>().DependsOn(Dependency.OnComponent(typeof(IUpdater), typeof(UpdaterC))).Named("DecoratedUpdaterC").LifestylePerWebRequest(),
            Component.For<UpdaterC>().ImplementedBy<UpdaterC>().LifestylePerWebRequest());
person Rudis    schedule 24.10.2013

Есть способы зарегистрировать сразу несколько компонентов.

Например, мы можем зарегистрировать все IUpdator в сборках в этом приложении, сделав их всех PerWebRequest и назвав имя их реализации следующим образом:

        container.Register(
            Classes.FromAssemblyInThisApplication()
                .BasedOn<IUpdator>()
                .Configure(registration => registration
                    .Named(registration.Implementation.Name)
                    .LifestylePerWebRequest()
                    ));

Мы также можем сделать так, чтобы компоненты получали все компоненты определенного типа, если мы используем встроенный преобразователь коллекции замков.

Если у нас есть такой класс:

    public class DecoratedComponent : IComponentThatNeedsAnArrayOfDecorators
    {
        public DecoratedComponent(IDecorator[] decorators)
        {

        }
    } 

Мы можем решить это так:

        IWindsorContainer container = new WindsorContainer();
        container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
        container.Register(
            Component.For<IComponentThatNeedsAnArrayOfDecorators>()
                .ImplementedBy<DecoratedComponent>());

        container.Resolve<IComponentThatNeedsAnArrayOfDecorators>();

В нашем декорированном компоненте теперь будут все наши декораторы.

Я не могу точно сказать, что вы пытаетесь сделать, но похоже, что это можно очистить такими методами.

person greyalien007    schedule 27.10.2013
comment
Хотелось бы более наглядно написать конфигурацию. В решении в моем вопросе легко написать ошибку, потому что я использовал много констант строки. - person Rudis; 28.10.2013
comment
Если декораторы имеют другой интерфейс, тогда легко написать автоматическую конфигурацию, но это не шаблон декоратора. Мне нужны реализации и декораторы с одинаковым интерфейсом, я мог бы установить их зависимости независимо от другого кода. - person Rudis; 28.10.2013