UnityContainer.Resolve或ServiceLocator.GetInstance?

zer*_*o51 13 c# dependency-injection inversion-of-control unity-container

这似乎是一个愚蠢的问题,因为在我的代码中一切正常,但我用Unity容器以这种方式注册了单例_ambientContainer:

 _ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)

为了避免使用我的本地字段,我使用:

get {
    return ServiceLocator.Current.GetInstance<Application.StateContext>();
}
Run Code Online (Sandbox Code Playgroud)

在我的get属性中获取我的对象的实例.这样我总是得到相同的实例(Application.StateContext仍然是单身)或GetInstance创建一个新的?

改为使用本地_ambientContainer字段会更好吗?

get {
    return _ambientContainer.Resolve<Application.StateContext>();
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Enr*_*lio 19

围绕容器消费类的实例传递一般不是一个好主意,因为你不再保证有一个在这里的组件和服务正在注册申请(被称为地方组成根).

类应该在它们的公共API中声明它们的依赖关系,理想情况是通过将它们指定为构造函数参数,容器将在被要求解析特定类型(称为自动装配的过程)时自动提供实例.

依赖注入通常是首选,但并不总是适用.在那些使用服务定位器的情况下,就像您在示例中所做的那样,是将类与其依赖关系分离的下一个最佳解决方案.

总之,如果依赖注入不是一个选项,我会避免让我的类直接引用容器,而是让它们通过服务定位器访问它.


Seb*_*ber 9

最好避免两种方式(ab)使用容器.

该服务定位被认为是一种反模式在现代应用架构.

  • 您有其他选择的建议吗?(特定于问题中的示例代码?) (2认同)
  • 如果您使用的方式错误,则任何模式都是反模式。所有DI库都在掩护下使用服务位置,否则它们将不起作用。不要相信您在互联网上阅读的所有内容! (2认同)
  • 是的,在某些时候,我们必须调用实际的实现类来接收类型的实例。坦白说,Microsoft为什么不将其烘焙到System.Activator.CreateInstance &lt;T&gt;中?我的意思是扯淡,我们都在这里错过了一个令人盲目的简单解决方案吗???? (2认同)

dev*_*tal 6

我假设ServiceLocator类型来自CommonServiceLocator项目,并且您正在使用Unity适配器,在这种情况下GetInstance调用container.Resolve,因此两行是等效的.

你可以在这里查看来源 - http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home