代码之家  ›  专栏  ›  技术社区  ›  Charles Prakash Dasari

害怕使用依赖注入框架

  •  4
  • Charles Prakash Dasari  · 技术社区  · 15 年前

    我一直在阅读依赖注入框架。我真的爱上了分离关注点并让对象完成他们的核心工作的想法——这无疑是一个优秀且长期的设计原则!

    然而,我对DI框架的了解越多,我就越担心: 1)以“自动”解决依赖关系的方式 2)关于配置文件中引入的极端复杂性

    就这一点而言2,我看到我的客户花费数百万美元来培训人们使用的产品,其中最重要的部分是如何“不”触摸配置文件。管理员现在害怕这些配置文件。

    不过,我看到了另一个称为服务定位器的模式,在该模式中,我可以很好地组装我在应用程序开始时想要的所有“全局”服务(可能是应用程序主机或应用程序上下文或其他)。使这个服务定位器在全球范围内可用,瞧!

    但是,我看到,当我需要基于某种标准(谁知道?)的多个“全局”服务类型时,使用服务定位器方法的灵活性会降低。!

    所以,在这里,我比以前更困惑的是该朝哪个方向走。虽然我非常喜欢设计原则,但是现有框架中的复杂性让我很失望!

    我的担心是真的吗?其他人也有同样的感觉吗?如果是这样的话,有没有什么好的方法可以替代如此压倒性的“框架”?

    6 回复  |  直到 8 年前
        1
  •  2
  •   TrueWill    15 年前

    正如内特提到的,“魔法”是可选的;如果你想要的话,你可以手工配置所有东西。

    我将避免配置文件最初(或永远!)并在代码中配置容器。这往往更容易阅读和维护。很多时候,您不需要对配置进行即时更改。客户不能触摸配置文件,因为它们不存在。

    服务定位器有缺点;首先,它们往往将类与定位器类/框架结合在一起。一个好的DI框架将允许您使用普通的旧对象;您的项目中可能只有一个实际使用DI/IOC框架的类。

    结构图和统一都很简单,给他们一个尝试。从小做起。

    下面是一个非常简单的Unity示例(包括内联配置):

    using Microsoft.Practices.Unity;
    
    static void Main()
    {
        using (IUnityContainer container = new UnityContainer())
        {
            container.RegisterType<IRobot, MrRoboto>();
    
            Console.WriteLine("Asking Unity container to give us a Model...");
    
            Model model = container.Resolve<Model>();
            model.MoveRobot();
        }
    }
    
    // class Model
    
    public Model(IRobot robot)
    {
        // Unity will hand the constructor an instance of MrRoboto!
    }
    
        2
  •  3
  •   Bryan Watts    15 年前

    我个人很喜欢使用 Autofac .容器配置是通过代码完成的,同时消除了冗长的XML并启用了重构支持。

    不过,最好的功能之一是 modules . 它们是容器配置的单元,允许您管理组成应用程序的许多不同组件的复杂性。

    我目前正在一个非常大的项目中工作,并且经验与小项目时大致相同,这意味着这种方法的规模非常大。

    启用DI的类的一个主要原则是它们不引用基础结构代码。这是服务定位器模式的对立面。服务定位器的主要缺点是,除了增加引用容器的类的复杂性之外,没有能力更改 哪个版本 解决了依赖关系。

    对于不引用容器的“纯”类,任何给定依赖项的解析版本都是被注入类的外部版本。

        3
  •  2
  •   Brent Writes Code    15 年前

    如果您真的在考虑采用依赖项注入路径,我强烈建议您快速阅读Martin Fowler的优秀依赖项注入文章:

    http://martinfowler.com/articles/injection.html

    我现在正在处理一个Java项目,里面有很多配置文件。我们选择了前面的单例模式来表示我们的配置(有点类似于全局解决方案)。以下是一些让我发疯的事情,让我希望我们有一个依赖注入模式:

    1. 全球化模式的单元测试很糟糕。依赖注入模式很容易实现单元测试,尤其是模拟对象测试。在单例类型的情况下,您现在拥有了所有这些单元测试,它们仍然需要一个可用的全局状态才能运行。通过依赖注入,您可以生成传递到测试中的特定于测试的模拟配置对象。我不能夸大这会使单元测试变得多么容易。另一篇题为“Endo测试:模拟对象的单元测试”的优秀论文: http://connextra.com/aboutUs/mockobjects.pdf

    2. 使用全球化的方法在较小的系统中工作得更好,但是随着线程数量的增加,它们都开始争夺配置资源。您可能会遇到同步问题,您的配置访问甚至可能开始成为瓶颈。这对我们来说还不是一个大问题,但它已经开始让我们所有人恼火。

    3. 一旦你沿着一条非依赖注入路径走了一小段路,就没有真正的回头路了。从依赖注入到某种全球化模式是令人讨厌的,但可以逐步实现。试图从全球化模式返回依赖注入是一场噩梦。我一直想在我们的项目中实现它,但我做不到。这需要一个完整的开发周期。

    无论如何,希望这篇文章和经验能帮助你做出决定。我已经走了很长一段路了,你想走下去,我有点希望我们可以走依赖注入的路线。

        4
  •  1
  •   Undo ptrk    8 年前

    这些都不是DI所必需的——它们是由一些DI框架提供的选项。就我个人而言,我也不喜欢“automagic”注入——我可以看到它在非常小的项目中工作,但在较大的项目中会引起问题。对于点2-我不确定我明白点-我主要用的是弹簧。Spring既提供XML配置,又提供Java配置选项。它提供嵌套配置。如果有一部分配置不想让任何人改变,那么就有一部分你要做的——把它们分成单独的配置文件——或者“可变”一个XML和另一个Java。Spring还支持使用属性文件中的值,这是我希望管理员所做的全部更改——管理员不是程序员——他们不应该“重新连接”您的应用程序——只是提供适当的选项。

        5
  •  0
  •   James Black    15 年前

    根据您使用的语言的不同,有些DI框架并不可怕,尽管您将拥有一些配置文件,但它们不应该可怕,但很有用。

    例如,我有一个用于开发的配置文件,一个用于测试,一个用于生产。

    因此,根据我使用的数据库连接,可以更改数据库连接,我可以换出数据库层进行测试,并使用模拟测试。

    系统管理员应该控制生产配置文件,因为开发人员不应该将任何东西推送到生产环境中,理想情况下。

    春季有一个很好的DI设置,虽然它不是轻量级的。

    我发现Unity框架并不容易学习,但是一旦使用了它,就很容易添加新的注入类。

    所以,任何新的东西最初都可能很可怕,但是当您对这个概念感到满意时,您可以看到一些优势,比如我解释了三个配置文件。

        6
  •  0
  •   Aneurysm9    15 年前

    我的情况可能不同于您的情况,因为我们已经为非常灵活的配置设计了一个系统,因此向该配置添加依赖项注入几乎是微不足道的,但在我看来,使用服务定位器模式不会为您节省很多配置,因为您仍然必须指定如何定位服务。能够灵活地为测试注入模拟对象对于使用依赖注入几乎是无价的好处,所以我想说,配置开销可能只是为了获得好处而需要接受的业务成本。

    推荐文章