【问题标题】:Injecting a property into a singleton service in Prism (Unity, MVVM)将属性注入 Prism 中的单例服务(Unity,MVVM)
【发布时间】:2015-06-16 09:52:00
【问题描述】:

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

public class BeckhoffService: IProgrammableLogicController
{ ...}

我要么想要这个:

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

或在构造函数中:

BeckhoffService(IEventAggregator eventAggregator)

当我在统一容器中将此服务注册为单例时,我的问题就出现了。

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

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

以上内容正确注册为单例,但“controllerSingleton”中的依赖项没有得到解析。

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

上面解决了“new BeckhoffService()”中的依赖,但是容器在解决的时候没有返回单例实例。

我可以通过手动将 IEventAggregator 传递给 Beckhoff 服务来实现它,而无需将 Unity Container 直接注入到服务中,但这似乎有点难看:

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

有没有更好或更喜欢的方式来完成我想要的?谢谢!

【问题讨论】:

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


    【解决方案1】:

    哪些依赖项?

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

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

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

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

    例如:

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

    然后用

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

    ContainerControlledLifetimeManager 生命周期管理器相当于 Unity 的单例(技术上非常接近它),至于容器的生命周期,总是会返回相同的实例。由于您的组合根位于接近应用程序启动的位置(至少应该如此,否则您可能会遇到问题),主 IoC 容器通常与应用程序一样存在。

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

    通常您将RegisterInstance 用于不可解析的类型(即第 3 方库)或需要配置(例如,如果您想配置记录器服务的实例)。然后你自己实例化它,配置它并将它作为实例注册到 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);
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-07
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多