2015-04-10 1 views
0

Для справки у меня есть служба, которую я хочу зарегистрировать в качестве единственного контейнера в контейнере единства. Я хочу, чтобы эта служба имела IEventAggerator, введенный в службу каким-то образом, либо путем вложения свойств, либо с помощью конструктора.Внедрение свойства в однопользовательскую службу в Prism (Unity, MVVM)

public class BeckhoffService: IProgrammableLogicController 
{ ...} 

и я либо хочу это:

[Dependency] 
public IEventAggregator eventAggregator{get;set;} 

или в конструкторе:

BeckhoffService(IEventAggregator eventAggregator) 

Моя проблема возникает, когда я зарегистрировать эту услугу в единстве контейнера как синглтон.

В моем модуле Initialize, эти варианты я пробовал:

IProgrammableLogicController controllerSingleton = new BeckhoffService(); 
_container.RegisterInstance<IProgrammableLogicController>(controllerSingleton); 

выше правильно регистрируется как синглтон, но в зависимости «controllerSingleton» не разрешаются.

_container.RegisterInstance<IProgrammableLogicController>(new BeckhoffService()); 

выше решает зависимости в «новой BeckhoffService()», но контейнер не возвращает одноэлементный экземпляр, когда она будет решена.

я был в состоянии осуществить это, передавая IEventAggregator в службу Beckhoff вручную без контейнера Unity нагнетания в службу непосредственно, но это, казалось, вроде некрасиво:

IProgrammableLogicController controllerSingleton = new BeckhoffService(_container.Resolve<IEventAggregator>()); 
_container.RegisterInstance<IProgrammableLogicController>(controllerSingleton); 

Есть ли лучше или более предпочтительным способ выполнения того, что я хочу? Благодаря!

ответ

3

Какие зависимости?

IProgrammableLogicController controllerSingleton = new BeckhoffService(); 
_container.RegisterInstance<IProgrammableLogicController>(controllerSingleton); 

В первом примере, вы инициализировать BeckhoffService() себя и с помощью конструктора без параметров, поэтому, конечно, вы не получите ничего впрыскивается.

То же самое для вашего второго примера. Вы инициализируете объект самостоятельно, а не через контейнер IoC.

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

Например:

container.Register<IProgrammableLogicController, BeckhoffService>(new ContainerControlledLifetimeManager()); 

, а затем решить его с

IProgrammableLogicController controller = container.Resolve<IProgrammableLogicController>(); 

ContainerControlledLifetimeManager срок службы менеджер Единство эквивалент одноточечного (технически довольно близко к ней), так как в течение срока службы контейнера , всегда возвращается тот же экземпляр. Так как ваш корневой состав лежит в начале приложения (по крайней мере, он должен, если не вы можете получить проблемы), основной контейнер IoC обычно живет до тех пор, пока App живёт.

Unity также позволяет создавать дочерние контейнеры, если вам нужны одиночные игры для определенной цепочки операций, вы создадите дочерний контейнер, и в этой операции IoC будет возвращать всегда тот же экземпляр.Как только операция будет завершена, вы удалите контейнер, и следующая операционная цепочка снова создаст повторяющиеся синглтоны на протяжении всей этой операции и т. Д.

Обычно вы используете RegisterInstance для типов, которые не подлежат разрешению (то есть сторонняя библиотека) или необходимости конфигурации (например, если вы хотите настроить экземпляр службы регистрации). Затем вы создадите экземпляр самостоятельно, настройте его и зарегистрируйте в качестве экземпляра IoC. Это действительно для конфигурации во время настройки графика объекта.

Если у вас есть классы, для которых требуются только зависимости и нет конфигурации/инициализации, вы должны использовать метод RegisterType.

Если у вас есть классы, для которых требуется определенный параметр или зависимость во время выполнения, вам необходимо реализовать «Абстрактную фабрику» и создать/разрешить экземпляр с помощью метода, который запрашивает параметр. Это позволяет избежать того, что вы забыли вызвать методы настройки объектов.

Bad:

// ctor 
public MyClass(IMyDependency dep) { 
    dep.RuntimeDependencyValue = 42; // Bad if RuntimeDependencyValue is required for the class to work 

    // or 
    dep.Initialize(42); 
} 

Лучше:

public MyClass(IMyDependencyFactory depFactory) { 
    IMyDependency dep = depFactory.Create(42); 
} 

Второй один лучше, потому что абстрактном Решимость/создания плюс инициализации позади класса фабрики. Теперь вы не можете пропустить инициализацию с важными параметрами, так как единственный способ создать его - это метод, который заставляет вас передать требуемый параметр.