Castle Windsor IoC Контейнерная установка для нескольких типов бетона - PullRequest
1 голос
/ 07 октября 2011

Я новичок в IoC и Castle Windsor.

Вопрос больше относится к IoC, но я просто выбрал Castle в качестве своего предпочтительного оружия.

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

Единственный способ, который мне подходит, - это использовать функцию Builder, которая будет каждый раз создавать весь контейнер, а затем позволять мне указыватьтипы, посмотрите на этот пример:

У меня есть представление:

public interface IView
{
}

Есть 2 конкретных реализации этого представления:

public class ConcreteViewA : IView
{
}

public class ConcreteViewB : IView
{
}

У меня есть контроллер, которыйоперирует с представлением:

public class Controller
{
    public Controller(IView view) { }
    public void Load() { }
}

Я создаю функцию, которая создает мой контейнер IoC и регистрирует общие типы, единственный тип, который я могу зарегистрировать, - это мой контроллер, так как все это остается неизменным:

WindsorContainer BuildContainer()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<Controller>().ImplementedBy<Controller>());
        return container;
    }

У меня есть 2 (корневые) точки входа:

void RootMethod1()
    {
        var container = BuildContainer();
        container.Register(Component.For<IView>().ImplementedBy<ConcreteViewA>());
        var controller = container.Resolve<Controller>();
        controller.Load();
    }

    void RootMethod2()
    {
        var container = BuildContainer();
        container.Register(Component.For<IView>().ImplementedBy<ConcreteViewB>());
        var controller = container.Resolve<Controller>();
        controller.Load();
    }

Как вы видите, мне приходится каждый раз перестраивать контейнер, так как мне нужно указать, что использовать для IView для каждогоконтекстаЯ нахожусь в. Что, если Контейнер дорогой, чтобы восстановить (много типов и т. д.), как я могу спроектировать это?

Ответы [ 2 ]

5 голосов
/ 11 октября 2011

Из того, что я понимаю, вам нужны два разных экземпляра класса Controller (каждый из которых имеет свой тип IView). Самый простой способ добиться этого - зарегистрировать два компонента с разными именами и разными зависимостями.

WindsorContainer BuildContainer()
{
    var container = new WindsorContainer();

        container.Register(Component.For<Controller>().Named("ControllerWithViewA")
                                                      .ImplementedBy<Controller>()
                                                      .DependsOn(Property.ForKey(typeof(IView))
                                                      .Is(typeof(ConcreteViewA)));
        container.Register(Component.For<Controller>().Named("ControllerWithViewB")
                                                     .ImplementedBy<Controller>()
                                                     .DependsOn(Property.ForKey(typeof(IView))
                                                     .Is(typeof(ConcreteViewB)));
    return container;
}

Затем вы можете запросить любой контроллер по мере необходимости.

void RootMethod1()
{
    var container = BuildContainer();
    var controller = container.Resolve<Controller>("ControllerWithViewA");
    controller.Load();
}

void RootMethod2()
{
   var controller = container.Resolve<Controller>("ControllerWithViewB");
   controller.Load();
}

Еще несколько вещей, которые следует иметь в виду при использовании DI

  1. Создайте свой контейнер только один раз (Строительство его снова и снова - пустая трата времени и ресурсов).

  2. Будьте уверены, какие зависимости вводить, а какие нет. Чрезмерное использование ДИ для всего может привести к раздутому контейнеру, который станет кошмаром для обслуживания.

  3. Будьте в курсе жизненного цикла ваших компонентов (Singleton, Transient, на поток и т. Д.). Особенно с Каслом стиль жизни по умолчанию - синглтон, который может создать противоречивое поведение в многопоточном сценарии.

1 голос
/ 08 октября 2011

Вы можете посмотреть, используя селектор обработчика. Это позволит вам динамически выбирать, какое представление разрешать, основываясь на любом выбранном вами коде. Смотрите здесь .

...