在Prism(Unity,MVVM)中将属性注入单例服务 [英] Injecting a property into a singleton service in Prism (Unity, MVVM)

查看:578
本文介绍了在Prism(Unity,MVVM)中将属性注入单例服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为参考,我有一项服务,我想在unity容器中注册为单例。我希望此服务通过属性或构造函数注入以某种方式将IEventAggerator注入该服务。

For reference, I have a service that I want to register as a singleton in the unity container. I want this service to have the IEventAggerator injected into the service somehow, either by property or constructor injection.

public class BeckhoffService: IProgrammableLogicController
{ ...}

,而我要么想要:

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

或在构造函数中:

BeckhoffService(IEventAggregator eventAggregator)

我将这个服务作为一个单例注册到统一容器中时出现问题。

My issue comes when I register this service in the unity container as a singleton.

在我的模块初始化中,这些是我已经选择的选项尝试过:

In my module Initialize, these are the options I've tried:

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

以上内容正确注册为单例,但 controllerSingleton中的依赖项未得到解决。 / p>

The above correctly registers as a singleton, but the Dependencies in "controllerSingleton" do not get resolved.

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

以上方法解决了 new BeckhoffService()中的依赖项,但容器未返回单例实例

The above resolves the dependencies in "new BeckhoffService()" but the container does not return the singleton instance when it is resolved.

我能够通过将IEventAggregator手动传递到Beckhoff服务中而无需将Unity Container直接注入该服务中来实现它,但这似乎有点丑陋的:

I was able to implement it by passing the IEventAggregator into the Beckhoff service manually without the Unity Container injecting into the service directly, but that seemed sort of ugly:

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

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

Is there a better or more preferred way of accomplishing what I want? Thanks!

推荐答案

哪个依赖项?

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

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

In your first example, you initialize BeckhoffService() yourself and using a parameterless constructor, so of course you won't get anything injected.

与您的第二个示例相同。您可以自己初始化对象,而不是通过IoC容器初始化。

Same for your second example. You initialize the object yourself, not through the IoC container.

您要么必须自己初始化类并自己传递依赖项,要么必须将类型注册到IoC容器并让容器对其进行解析!

You either have to initialize the class yourself and pass the dependencies yourself, or you have to register the types to your IoC container and have the container resolve it!

例如:

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

,然后使用

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

ContainerControlledLifetimeManager 生命周期管理器与Unity等效就容器的生存期而言,单例(从技术上来说很接近),将始终返回相同的实例。由于您的合成根位于接近应用程序开始的位置(至少应该如此,如果没有,您可能会遇到问题),因此,主IoC容器通常只要应用程序存在就可以存在。

The ContainerControlledLifetimeManager lifetime manager is Unity equivalent of singleton (technically pretty close to it), as for the lifetime of the container, always the same instance will be returned. Since your composition root lies closing to the App start (at least it should, if not you may get issues), the main IoC container usually lives as long as the App lives.

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

Unity also allows creating of child containers, if you need singletons for a specific operation chain, you'd create a child container and within this operation the IoC would return always same instance. Once the operation is finished, you dispose the container and next operation chain will instantiate the singletons again for the duration of that operation etc.

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

Usually you use RegisterInstance for types which aren't resolvable (i.e. 3rd party library) or need configuration (for example if you want to configure an instance of a logger service). Then you'd instantiate it yourself, configure it and register it to the IoC as instance. This is valid for configuration during the object graph setup.

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

If you have classes, which only require dependencies and no configuration/initialization, you should use the RegisterType method.

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

If you have classes, which require a certain parameter or dependency at run time, you need to implement an "Abstract Factory" and create/resolve the instance via a method which requests the parameter. This avoids that you forget to call an objects configuration methods.

错误:

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

第二个比较好,因为抽象解析/创建以及工厂后面的初始化类。现在,您不会错过使用重要参数进行初始化的方法,因为创建该方法的唯一方法是强制您传递必需参数的方法。

Second one is better, because abstract the resolve/creation plus initialization behind the factory class. Now you can't miss to initialize it with important parameters, as the only way to create it is by a method which force you to pass the required parameter.

这篇关于在Prism(Unity,MVVM)中将属性注入单例服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆