[Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 08:19
Оценка:
Мое знакомство с Unity началось вот с такого кода в проекте WPF:


 var container = new UnityContainer();
            container
                .RegisterType<ViewModel>(new ContainerControlledLifetimeManager())
                .RegisterType<ICalcService, CalcService>();

            container.Resolve<MainWindow>().Show();

Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.
Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
Re: [Unity] Где создавать UnityContainer
От: LF  
Дата: 08.09.10 08:30
Оценка: 2 (1)
S>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.
S>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
Два пути:
1) Создать синглтон. Я, например, делал статический класс вроде этого
  Скрытый текст
    public static class DI
    {
        private static IUnityContainer Container { get; set; }

        static DI()
        {
            Container = new StubContainer();
        }

        ///<summary>
        ///</summary>
        public static void RegisterContainer(IUnityContainer newContainer)
        {
            Container = newContainer;
        }

        ///<summary>
        ///</summary>
        public static void Register<TFrom, TTo>() where TTo : TFrom
        {
            Container.RegisterType<TFrom, TTo>();
        }

        ///<summary>
        ///</summary>
        public static void RegisterAsSingleton<TFrom, TTo>() where TTo : TFrom
        {
            Container.RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager());
        }

        ///<summary>
        ///</summary>
        public static void Register<TFrom>(TFrom instance)
        {
            Container.RegisterInstance(instance);
        }

        ///<summary>
        ///</summary>
        public static T Resolve<T>()
        {
            return Container.Resolve<T>();
        }

        ///<summary>
        ///</summary>
        public static object Resolve(Type t)
        {
            return Container.Resolve(t);
        }

        ///<summary>
        ///</summary>
        public static T Resolve<T>(string name)
        {
            return Container.Resolve<T>(name);
        }

        ///<summary>
        ///</summary>
        public static void BuildUp<T>(T item)
        {
            Container.BuildUp(item);
        }
    }

2) передавать контейнер в каждый класс.

Второй подход мне кажется более кошерным, но и использовать его сложнее.
Re[2]: [Unity] Где создавать UnityContainer
От: LF  
Дата: 08.09.10 08:36
Оценка:
LF>2) передавать контейнер в каждый класс.
LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.
Есть еще такой фокус, регистрировать контейнер в самом себе.
Тогда он будет сам себя резолвить при создании объектов.
Re[3]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 08:39
Оценка:
Здравствуйте, LF, Вы писали:

LF>>2) передавать контейнер в каждый класс.

LF>>Второй подход мне кажется более кошерным, но и использовать его сложнее.
LF>Есть еще такой фокус, регистрировать контейнер в самом себе.
LF>Тогда он будет сам себя резолвить при создании объектов.

Хех! Прикольно! Реально фокус
Re[2]: [Unity] Где создавать UnityContainer
От: Аноним  
Дата: 08.09.10 08:40
Оценка: +1
Здравствуйте, LF, Вы писали:

S>>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.

S>>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
LF>Два пути:
LF>1) Создать синглтон. Я, например, делал статический класс вроде этого

синглтон для DI это что-то.

LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.



class Foo
{
    public Foo(IContainer container)
    {
        ...
    }

    ...
}

...

var foo = container.Resolve<Foo>();

...


В чём сложность?
Re[3]: [Unity] Где создавать UnityContainer
От: LF  
Дата: 08.09.10 08:43
Оценка:
А>В чём сложность?
Есть моменты, когда управлять созданием объектов не можешь, следовательно, и написать
var foo = container.Resolve<Foo>();

не получится.
Re: [Unity] Где создавать UnityContainer
От: TK Лес кывт.рф
Дата: 08.09.10 08:45
Оценка:
Здравствуйте, skodnik, Вы писали:

S>Мое знакомство с Unity началось вот с такого кода в проекте WPF:

S>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.

Смотря для чего он вам требуется. Вам надо заниматься конфигурированием контейнера или просто выполнить Resolve / BuildUp ?

S>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?


Так можно дойти до того, что будет создан синглтон для ICalcService и все плюсы Unity сойдут на нет.
Если объекту нужен сервис — его туда надо заинжектить. В этом плане, IUnityContainer мало чем отличается от ICalcService
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 08:49
Оценка:
Здравствуйте, LF, Вы писали:

LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.


Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее?
Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс.
Re[2]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 08:50
Оценка:
Здравствуйте, TK, Вы писали:



TK>Смотря для чего он вам требуется. Вам надо заниматься конфигурированием контейнера или просто выполнить Resolve / BuildUp ?


второе
Re[3]: [Unity] Где создавать UnityContainer
От: LF  
Дата: 08.09.10 08:50
Оценка:
S>Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее?
S>Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс.
Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще.
Re[4]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 08:53
Оценка: :)
Здравствуйте, LF, Вы писали:

S>>Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее?

S>>Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс.
LF>Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще.
Используя Unity — мы таки боремся с зависимостями или нет?
Re[5]: [Unity] Где создавать UnityContainer
От: LF  
Дата: 08.09.10 08:56
Оценка:
LF>>Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще.
S>Используя Unity — мы таки боремся с зависимостями или нет?
Используя unity мы боремся с неявными зависимостями.
Все от чего зависит класс мы выносим в параметры конструктора/свойства, следовательно, можем безболезненно подменять.
Re[3]: [Unity] Где создавать UnityContainer
От: TK Лес кывт.рф
Дата: 08.09.10 08:57
Оценка:
Здравствуйте, skodnik, Вы писали:

TK>>Смотря для чего он вам требуется. Вам надо заниматься конфигурированием контейнера или просто выполнить Resolve / BuildUp ?

S>второе

Заведите для этого специальный интерфейс (или IServiceProvider если подходит) и инжектите его всем средствами Unity.
Плюс подобного подхода (отказ от синглтона) в том, что можно создавать дочерние контейнеры и тем самым предоставлять более гибкий набор сервисов для подчиненных объектов.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 09:09
Оценка: 5 (2) +2
Здравствуйте, skodnik, Вы писали:

S>Мое знакомство с Unity началось вот с такого кода в проекте WPF:



S>
S> var container = new UnityContainer();
S>            container
S>                .RegisterType<ViewModel>(new ContainerControlledLifetimeManager())
S>                .RegisterType<ICalcService, CalcService>();

S>            container.Resolve<MainWindow>().Show();

S>

S>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.
S>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?

Ни то, ни другое.

В принципе программа должна выглядеть так

var container =   new UnityContainer()...
var rootObject = container.Resolve<SomeRootObject>();
Run(rootObject);


Но на деле далеко не всегда можно контролировать создание объектов (например asp.net), а также не всегда можно перехватить этап создания объекта, тогда проще с синглтоном.

Если нужно динамическое создание объектов, то лучше создавать объекты — фабрики и инжектить их в нужные классы, а фабрика уже может иметь зависимость от IUnityContainer, которая инжектиться без телодвижений.
Re[3]: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 09:17
Оценка:
Здравствуйте, LF, Вы писали:

LF>>2) передавать контейнер в каждый класс.

LF>>Второй подход мне кажется более кошерным, но и использовать его сложнее.
LF>Есть еще такой фокус, регистрировать контейнер в самом себе.
LF>Тогда он будет сам себя резолвить при создании объектов.
Unity по-умолчанию так умеет.
Re[4]: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 09:19
Оценка:
Здравствуйте, LF, Вы писали:

А>>В чём сложность?

LF>Есть моменты, когда управлять созданием объектов не можешь, следовательно, и написать
LF>
LF>var foo = container.Resolve<Foo>();
LF>

LF>не получится.

Тогда можешь написать container.BuildUp(foo), в если не можешь перехватить объект до того как он будет использоваться, то тогда уже синглтон.
Re[2]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 09:37
Оценка:
Здравствуйте, gandjustas, Вы писали:


G>Ни то, ни другое.


G>В принципе программа должна выглядеть так


G>
G>var container =   new UnityContainer()...
G>var rootObject = container.Resolve<SomeRootObject>();
G>Run(rootObject);
G>


А допустим у меня есть MainWindow у которого есть свой ViewModel с некоторой командой, которая создает новое окно Window1 к нему создает ViewModel1 и выводит на экран.
Чтобы разорвать зависимости мне надо в ViewModel резолвить эти типы и создавать инстансы. Соотв. ViewModel должна иметь ссылку на контейнер.
Как тут быть?
Re[3]: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 10:02
Оценка: +1
Здравствуйте, skodnik, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:



G>>Ни то, ни другое.


G>>В принципе программа должна выглядеть так


G>>
G>>var container =   new UnityContainer()...
G>>var rootObject = container.Resolve<SomeRootObject>();
G>>Run(rootObject);
G>>


S>А допустим у меня есть MainWindow у которого есть свой ViewModel с некоторой командой, которая создает новое окно Window1 к нему создает ViewModel1 и выводит на экран.

S>Чтобы разорвать зависимости мне надо в ViewModel резолвить эти типы и создавать инстансы. Соотв. ViewModel должна иметь ссылку на контейнер.
S>Как тут быть?

Еще раз: фабрика.

У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.
Re[4]: [Unity] Где создавать UnityContainer
От: skodnik  
Дата: 08.09.10 10:07
Оценка:
Здравствуйте, gandjustas, Вы писали:


G>Еще раз: фабрика.


G>У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.


О! Точняк!
Re[5]: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 10:34
Оценка:
Здравствуйте, skodnik, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:



G>>Еще раз: фабрика.


G>>У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.


S>О! Точняк!


Любую проблему можно решать добавлением слоя абстракции, кроме проблемы наличия слишком большого количества слоев абстракции.

Кстати, кто-нить знает кто это в оригинале сказал?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.