繁体   English   中英

依赖注入或服务位置?

[英]Dependency injection or service location?

我正在尝试学习依赖注入,并且还有很多微妙之处我尚待掌握。 我为此而开始阅读的一本书是Karl Seguin的编程基础 有一个关于依赖注入的示例:

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);
        }
    } 
}

然后他继续建议添加一个间接级别,而不是直接在方法中调用ObjectFactory

public static class DataFactory
{
    public static IDataAccess CreateInstance
    {
        get
        {
            return ObjectFactory.GetInstance<IDataAccess>();
        }
    }
}

但是,实际上这不是“服务位置”吗?

它是服务定位器。 有几种使用依赖项的方法:

  • 汇总(示例案例)

  • 组成

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

    • 属性中的DI,可选(可以使用较高级别的SL注入)

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

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

首先,依赖注入比服务位置更费力,但是服务位置(SL)具有许多负面影响。 使用服务定位器实在太容易了,以至于到处疯狂地请求服务。 这很好,直到您进行重构并意识到耦合“太该死的太高”为止。

使用DI时,我更喜欢构造函数注入形式,因为它迫使我预先考虑谁需要什么。

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

您的示例是ServiceLocator。 总有一个ServiceLocator。 我要说的关键是要了解为什么您将直接使用它,以及为什么理想情况下不必使用它。

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

如果您使用的是诸如asp.net MVC之类的现代工具,那么您就可以访问所谓的合成根,它是应用程序的入口点。 在MVC中,它是控制器。 由于您可以访问合成根目录,因此无需使用ServiceLocator,因为注入是由您已经注册和设置的IOC框架从顶部驱动的。 基本上,控制器具有构造函数参数,例如ISomeService,该参数已在IOC中注册,并在创建控制器实例时自动注入。 如果ISomeService具有某些依赖关系,则它们也将以ISomeUtility的形式出现在构造函数中,依此类推,随着对象越来越深。 这是理想的选择,您将不需要使用ServiceLocator来解析对象。

如果您遇到的情况是使用的技术无法授予您对根的访问权限,或者您想开始在没有该应用程序的应用程序中使用IOC框架,而您是第一次添加它,则可以发现您无法到达合成词根。 这可能是框架或代码质量的限制。 在这些情况下,您必须使用ServiceLocator或直接自己创建对象。 在这些情况下,使用ServiceLocator是可以的,并且比自己创建该对象更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM