在Prism中将属性注入单件服务(Unity,MVVM)

时间:2015-04-10 15:39:56

标签: c# wpf dependency-injection unity-container prism

作为参考,我有一个服务,我想在Unity容器中注册为单例。我想要这个服务让IEventAggerator以某种方式注入服务,无论是通过属性还是构造函数注入。

public class BeckhoffService: IProgrammableLogicController
{ ...}

我想要这个:

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

或在构造函数中:

BeckhoffService(IEventAggregator eventAggregator)

当我在单位容器中将此服务注册为单身时,我的问题出现了。

在我的模块Initialize中,这些是我尝试的选项:

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

上面正确地注册为单例,但是&#34; controllerSingleton&#34;中的依赖项。不要解决。

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

以上解决了&#34;新BeckhoffService()&#34;中的依赖关系。但是在解析时,容器不会返回单例实例。

我能够通过将IEventAggregator手动传递到Beckhoff服务而不将Unity容器直接注入服务来实现它,但这看起来有点难看:

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

是否有更好或更优选的方式来实现我想要的东西?谢谢!

1 个答案:

答案 0 :(得分:3)

哪些依赖?

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

在您的第一个示例中,您自己初始化BeckhoffService()并使用无参数构造函数,因此您当然不会注入任何内容。

第二个例子也是如此。您自己初始化对象,而不是通过IoC容器。

您必须自己初始化类并自行传递依赖项,或者您必须将类型注册到IoC容器并让容器解决它!

例如:

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

然后用

解决它
IProgrammableLogicController controller = container.Resolve<IProgrammableLogicController>();

ContainerControlledLifetimeManager生命周期管理器是Unity等效的singleton(技术上非常接近它),就容器的生命周期而言,总是会返回相同的实例。由于你的组合根目标是关闭App开始(至少它应该,如果不是你可能会遇到问题),主要的IoC容器通常只要应用程序存在就会存在。

Unity还允许创建子容器,如果您需要特定操作链的单例,您将创建一个子容器,并且在此操作中IoC将始终返回相同的实例。操作完成后,您将处置容器,下一个操作链将在该操作期间再次实例化单例。

通常,对于不可解析的类型(即第三方库)或需要配置(例如,如果要配置记录器服务的实例),请使用RegisterInstance。然后你自己实例化它,配置它并将它作为实例注册到IoC。这对于对象图设置期间的配置有效。

如果您有只需要依赖项而没有配置/初始化的类,则应使用RegisterType方法。

如果您有在运行时需要特定参数或依赖项的类,则需要实现“抽象工厂”并通过请求参数的方法创建/解析实例。这可以避免您忘记调用对象配置方法。

坏:

// 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);
}

第二个更好,因为抽象的解析/创建加上工厂类后面的初始化。现在你不能错过用重要参数初始化它,因为创建它的唯一方法是强制你传递所需参数的方法。