C# UnityContainer.Resolve 还是 ServiceLocator.GetInstance?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9308424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:49:51  来源:igfitidea点击:

UnityContainer.Resolve or ServiceLocator.GetInstance?

c#dependency-injectioninversion-of-controlunity-container

提问by zero51

It could seem a stupid question because in my code everything is working, but I've registered a singleton this way with my Unity container _ambientContainer:

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

 _ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager());

In order to avoid to use my local field, I use:

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

get {
    return ServiceLocator.Current.GetInstance<Application.StateContext>();
}

inside my get property to get an instance of my object. This way I get always the same instance (Application.StateContextis still a singleton) or does GetInstancecreate a new one?

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

Is it better to use the local _ambientContainerfield instead?

使用本地_ambientContainer字段更好吗?

get {
    return _ambientContainer.Resolve<Application.StateContext>();
}

Thank you.

谢谢你。

采纳答案by devdigital

I'm assuming that the ServiceLocatortype is from the CommonServiceLocatorproject, and that you're using the Unity adapter, in which case GetInstanceinvokes container.Resolve, so both lines are equivalent.

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

You can view the source here - http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home

您可以在此处查看源代码 - http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home

回答by Sebastian Weber

Preferably you should avoid both ways of (ab)using your container.

最好你应该避免(ab)使用你的容器的两种方式。

The ServiceLocator is considered an anti-patternin modern application architecture.

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

回答by Enrico Campidoglio

Passing around instances of the container to consumer classes isn't generally a good idea, since you are no longer guaranteed to have a singleplace in your application where components and services are being registered (known as the Composition Root).

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

Classes should state their dependencies in their public API, ideally by specifying them as constructor arguments, which the container will automatically provide an instance for whenever it's been asked to resolve a specific type (a process known as Autowiring).

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

Dependency Injectionis usually the preferred choicebut it isn't always applicable. In those cases using a Service Locator, like you're doing in your example, is the next bestsolution to decouple a class from its dependencies.

依赖注入通常是首选,但并不总是适用。在这些情况下,使用Service Locator,就像您在示例中所做的那样,是将类与其依赖项分离下一个最佳解决方案。

In conclusion, if Dependency Injection is not an option, I would avoid having my classes reference the container directly and instead have them access it through a Service Locator.

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