[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>О! Точняк!


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

Кстати, кто-нить знает кто это в оригинале сказал?
Re[6]: [Unity] Где создавать UnityContainer
От: Аноним  
Дата: 08.09.10 10:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


G>Кстати, кто-нить знает кто это в оригинале сказал?


Буч?
Re[7]: [Unity] Где создавать UnityContainer
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.09.10 11:15
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


G>>Кстати, кто-нить знает кто это в оригинале сказал?


А>Буч?


Ссылку?
Re[8]: [Unity] Где создавать UnityContainer
От: Andy77 Ниоткуда  
Дата: 08.09.10 19:32
Оценка: 21 (1)
G>Ссылку?

Гугл?

A famous aphorism of Butler Lampson goes: All problems in computer science can be solved by another level of indirection;[2] this is often deliberately mis-quoted with "abstraction" substituted for "indirection". David Wheeler's corollary to this is, "...except for the problem of too many layers of indirection."
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.