C# 依赖注入还是服务位置?

C# 依赖注入还是服务位置?,c#,language-agnostic,loose-coupling,service-locator,C#,Language Agnostic,Loose Coupling,Service Locator,我正在努力学习依赖注入,它有许多微妙之处我还没有掌握。为此我开始阅读的一本书是卡尔·塞根的《圣经》。有一个关于依赖项注入的示例: public class Car { private int _id; public void Save() { if (!IsValid()) { //todo: come up with a better exception throw new Invalid

我正在努力学习依赖注入,它有许多微妙之处我还没有掌握。为此我开始阅读的一本书是卡尔·塞根的《圣经》。有一个关于依赖项注入的示例:

public class Car
{
    private int _id;

    public void Save()
    {
        if (!IsValid())
        {
            //todo: come up with a better exception
            throw new InvalidOperationException("The car must be in a valid state");
        }

        IDataAccess dataAccess = ObjectFactory.GetInstance<IDataAccess>();
        if (_id == 0)
        {
            _id = dataAccess.Save(this);
        }
        else
        {
            dataAccess.Update(this);
        }
    } 
}

但这不是“服务地点”吗?

是的,在我看来很像SL。依赖注入传统上遵循两种模式之一;属性注入或构造函数注入

依赖注入一开始感觉比服务位置更费劲,但服务位置(SL)有许多缺点。有了服务定位器,你就很容易发疯,一时兴起,到处请求服务。这是好的,直到你去重构,并意识到耦合是“太他妈的高”

对于DI,我更喜欢构造函数注入表单,因为它迫使我提前考虑谁需要什么


综上所述,我当前的项目是作为一个使用服务定位器的绿色领域项目启动的,因为它给了我“不”考虑依赖关系和让应用程序形状演变的灵活性。最近我一直在重构以使用DI,主要是为了弄清楚什么依赖于什么以及为什么依赖于什么。

是的,在我看来像SL。依赖注入传统上遵循两种模式之一;属性注入或构造函数注入

依赖注入一开始感觉比服务位置更费劲,但服务位置(SL)有许多缺点。有了服务定位器,你就很容易发疯,一时兴起,到处请求服务。这是好的,直到你去重构,并意识到耦合是“太他妈的高”

对于DI,我更喜欢构造函数注入表单,因为它迫使我提前考虑谁需要什么


综上所述,我当前的项目是作为一个使用服务定位器的绿色领域项目启动的,因为它给了我“不”考虑依赖关系和让应用程序形状演变的灵活性。最近我一直在重构以使用DI,主要是为了弄清楚什么依赖于什么以及为什么依赖于什么。

这是服务定位器。有几种使用依赖关系的方法:

  • 聚合(示例)

  • 构图

    • 构造函数中的DI,强制(可以在上层使用SL注入)

    • 属性中的DI,可选(可以在上层使用SL注入)


选择什么取决于许多因素,例如它是稳定的还是不稳定的依赖关系,是否需要在测试中模拟它等等。Mark Seemann有一本关于DI的好书,名为《在.NET中注入依赖关系》。它是服务定位器。有几种使用依赖关系的方法:

  • 聚合(示例)

  • 构图

    • 构造函数中的DI,强制(可以在上层使用SL注入)

    • 属性中的DI,可选(可以在上层使用SL注入)


选择什么取决于许多因素,例如它是稳定的还是不稳定的依赖关系,您是否需要在测试中模拟它等等。Mark Seemann有一本关于DI的好书,名为《.NET中的依赖项注入》。

您的例子是ServiceLocator。总有一个ServiceLocator在某处。我想说,关键是要理解为什么你会直接使用它,以及为什么理想情况下你可能不必使用它

关键概念是依赖项反转原理。依赖注入和控制框架反转是促进主体应用的工具。理想情况下,您希望对象构造函数参数是接口定义,这些接口定义将在对象创建时解析

如果您使用的是现代工具,例如asp.net MVC,那么您可以访问所谓的组合根,它是应用程序的入口点。在MVC中,它是控制器。因为您可以访问composition根目录,所以不需要使用ServiceLocator,因为注入是由您的IOC框架从顶部驱动的,您应该已经注册并设置了IOC框架。基本上,您的控制器具有构造函数参数,如ISomeService,它在IOC中注册,并在创建控制器实例时自动注入。如果ISomeService有一些依赖项,它们也会作为ISomeUtility出现在构造函数中,等等,随着对象越来越深。这非常理想,您永远不需要使用ServiceLocator来解析对象


如果您使用的技术不允许您访问根目录,或者如果您想在没有IOC框架的应用程序中开始使用IOC框架,并且您是第一次添加它,那么您可能会发现无法访问合成根目录。这可能是框架或代码质量的限制。在这些情况下,您必须使用ServiceLocator或直接自己创建对象。在这些情况下,使用ServiceLocator是可以的,并且比自己创建对象要好。

您的示例是ServiceLocator。总有一个ServiceLocator在某处。我想说,关键是要理解为什么你会直接使用它,以及为什么理想情况下你可能不必使用它

关键概念是依赖项反转原理。依赖注入和控制框架反转是促进主体应用的工具。理想情况下,您希望对象构造函数参数是接口定义,这些接口定义将在对象创建时解析

如果您使用的是现代工具,例如asp.net MVC,那么您可以访问所谓的组合根,它是应用程序的入口点。在MVC中,它是控制器。因为您可以访问composition根目录,所以不需要使用ServiceLocator,因为注入是由您的IOC框架从顶部驱动的,您应该已经注册并设置了IOC框架。基本上是你的控制
public static class DataFactory
{
    public static IDataAccess CreateInstance
    {
        get
        {
            return ObjectFactory.GetInstance<IDataAccess>();
        }
    }
}