作为参考,我有一个服务,我想在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);
是否有更好或更优选的方式来实现我想要的东西?谢谢!
答案 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);
}
第二个更好,因为抽象的解析/创建加上工厂类后面的初始化。现在你不能错过用重要参数初始化它,因为创建它的唯一方法是强制你传递所需参数的方法。