Мое знакомство с Unity началось вот с такого кода в проекте WPF:
var container = new UnityContainer();
container
.RegisterType<ViewModel>(new ContainerControlledLifetimeManager())
.RegisterType<ICalcService, CalcService>();
container.Resolve<MainWindow>().Show();
Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.
Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
S>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах. S>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
Два пути:
1) Создать синглтон. Я, например, делал статический класс вроде этого
LF>2) передавать контейнер в каждый класс. LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.
Есть еще такой фокус, регистрировать контейнер в самом себе.
Тогда он будет сам себя резолвить при создании объектов.
Здравствуйте, LF, Вы писали:
LF>>2) передавать контейнер в каждый класс. LF>>Второй подход мне кажется более кошерным, но и использовать его сложнее. LF>Есть еще такой фокус, регистрировать контейнер в самом себе. LF>Тогда он будет сам себя резолвить при создании объектов.
Здравствуйте, LF, Вы писали:
S>>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах. S>>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм? LF>Два пути: LF>1) Создать синглтон. Я, например, делал статический класс вроде этого
синглтон для DI это что-то.
LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.
class Foo
{
public Foo(IContainer container)
{
...
}
...
}
...
var foo = container.Resolve<Foo>();
...
Здравствуйте, skodnik, Вы писали:
S>Мое знакомство с Unity началось вот с такого кода в проекте WPF: S>Но в реальной жизни, сам контейнер требуется в разных методах и даже в разных классах.
Смотря для чего он вам требуется. Вам надо заниматься конфигурированием контейнера или просто выполнить Resolve / BuildUp ?
S>Необходимо самому создавать синглтон для контейнера, или Unity имеет свой механизм?
Так можно дойти до того, что будет создан синглтон для ICalcService и все плюсы Unity сойдут на нет.
Если объекту нужен сервис — его туда надо заинжектить. В этом плане, IUnityContainer мало чем отличается от ICalcService
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, LF, Вы писали:
LF>Второй подход мне кажется более кошерным, но и использовать его сложнее.
Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее?
Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс.
S>Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее? S>Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс.
Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще.
Здравствуйте, LF, Вы писали:
S>>Я тут с коллегой пообщался... нам таки непонятно чем второй способ кошернее, тем что он сложнее? S>>Слышал от "плюсовиков" что синглтоны это от лукавого для программистов с кривыми руками, которые не умеют в параметрах передать ссылку на инстанс. LF>Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще.
Используя Unity — мы таки боремся с зависимостями или нет?
LF>>Кошернее тем, что зависимость видно сразу в конструкторе, в случае синглтона зависимость не видно вообще. S>Используя Unity — мы таки боремся с зависимостями или нет?
Используя unity мы боремся с неявными зависимостями.
Все от чего зависит класс мы выносим в параметры конструктора/свойства, следовательно, можем безболезненно подменять.
Здравствуйте, skodnik, Вы писали:
TK>>Смотря для чего он вам требуется. Вам надо заниматься конфигурированием контейнера или просто выполнить Resolve / BuildUp ? S>второе
Заведите для этого специальный интерфейс (или IServiceProvider если подходит) и инжектите его всем средствами Unity.
Плюс подобного подхода (отказ от синглтона) в том, что можно создавать дочерние контейнеры и тем самым предоставлять более гибкий набор сервисов для подчиненных объектов.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, 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, которая инжектиться без телодвижений.
Здравствуйте, LF, Вы писали:
LF>>2) передавать контейнер в каждый класс. LF>>Второй подход мне кажется более кошерным, но и использовать его сложнее. LF>Есть еще такой фокус, регистрировать контейнер в самом себе. LF>Тогда он будет сам себя резолвить при создании объектов.
Unity по-умолчанию так умеет.
А допустим у меня есть MainWindow у которого есть свой ViewModel с некоторой командой, которая создает новое окно Window1 к нему создает ViewModel1 и выводит на экран.
Чтобы разорвать зависимости мне надо в ViewModel резолвить эти типы и создавать инстансы. Соотв. ViewModel должна иметь ссылку на контейнер.
Как тут быть?
S>А допустим у меня есть MainWindow у которого есть свой ViewModel с некоторой командой, которая создает новое окно Window1 к нему создает ViewModel1 и выводит на экран. S>Чтобы разорвать зависимости мне надо в ViewModel резолвить эти типы и создавать инстансы. Соотв. ViewModel должна иметь ссылку на контейнер. S>Как тут быть?
Еще раз: фабрика.
У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.
G>Еще раз: фабрика.
G>У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.
Здравствуйте, skodnik, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Еще раз: фабрика.
G>>У меня для этого случая был класс WindowManager, который создавал окна, он принимал IUnityContainer и имел довольно простую логику. А для целей тестирования вполне легко мокался.
S>О! Точняк!
Любую проблему можно решать добавлением слоя абстракции, кроме проблемы наличия слишком большого количества слоев абстракции.
Кстати, кто-нить знает кто это в оригинале сказал?