【问题标题】:Why don't languages integrate Dependency Injection at the core? [closed]为什么语言不在核心集成依赖注入? [关闭]
【发布时间】:2011-08-07 20:29:08
【问题描述】:

为什么语言不将依赖注入集成到它们的核心(在最低级别:可能是编译),因为依赖是复杂性理论中万恶之源?这样可以避免使用框架。

我更倾向于编译型语言。

我的问题类似于最近在 .NET 中动态引入的鸭子类型。为什么未来 DI 不做类似的事情?

【问题讨论】:

  • PHP 是一种脚本语言。我更倾向于编译语言。
  • 因为那样的话,该语言的用户将无法像孩子一样争论哪种框架最好。说真的,想象一下如果有人想出一种比语言实现的更好的方法来处理模式 X(在这种情况下是 DI)会发生什么?
  • 我的观点是没有框架,所以他不会问自己任何问题,因为这很自然:)
  • @user310291 - 不,人们只会争论语言的 模式 实现!一个模式可以通过多种方式实现;没有对错之分。这会导致主观性,因此任何语言尝试强制执行'仅以这种方式'只会将有关框架的争论带到整个语言!说到主观性,这可能就是为什么这个问题会在接下来的几分钟内结束!虽然@Aliostad 的回答对我来说是成功的。
  • 离题:从第一天开始,duck typing 就已经在 .NET 中了。例如,任何具有 GetEnumerator() 方法的对象都可以与 foreach 循环一起使用,它没有 来实现 IEnumerable..

标签: c# java frameworks dependency-injection inversion-of-control


【解决方案1】:

因为语言设计/设计模式中立的

【讨论】:

  • 依赖不是模式:它是关于复杂性的。能够注入任何类型的依赖应该是现代语言最想要和最自然的特性。
  • 回复:设计模式中立:C# 和 Java 都带有一个巨大的类库,可以被认为是语言的一部分,包含从集合到读取配置文件、到 XML 解析器、到日志记录的内容库和数据库驱动抽象层。可以想象,一个 DI 设施在这里不会完全不合适。
  • 我们不是在谈论 JDK 或 .NET Framework,我们在谈论 C# 或 Java 语言。语言是设计模式中立的,但可以,JDK or .NET Framework可以提供。
  • @Thilo:当然不是,事实上 DI 是 Java EE 6 API(JSR 330 和 299)的一部分
  • @Aliostad:语言不是设计模式中立的。从第一天起,作为观察者、迭代器和模板方法的模式就融入了 C# 语言。
【解决方案2】:

我个人可以看到这样做的好处。例如,我一直在编写这样的代码:

public class MyService : IService
{
    // Boilerplate!
    private readonly IDependency1 dep1;
    private readonly IDependency2 dep2;
    private readonly IDependency3 dep3;

    public MyService(IDependency1 dep1, IDependency2 dep2,
        IDependency3 dep3)
    {
        // More boilerplate!
        this.dep1 = dep1;
        this.dep2 = dep2;
        this.dep3 = dep3;
    }

    // Finally something useful
    void IService.DoOperation()
    {
       using (var context = this.dep1.CreateContext())
       {
           this.dep2.Execute(context);

           context.Commit();
       }

       this.dep3.Log("Success");
    }
}

能写成这样是不是很好:

public class MyService : IService
{
    public MyService(private IDependency1 dep1, 
        private IDependency2 dep2, private IDependency3 dep3)
    {
    }

    void IService.DoOperation()
    {
       using (var context = this.dep1.CreateContext())
       {
           this.dep2.Execute(context);

           context.Commit();
       }

       this.dep3.Log("Success");
    }
}

我希望我可以通过声明我的依赖字段并在我的构造函数中分配它们来省去所有的管道。

更新

我们的祈祷可能已经被听到了。 C# 团队might be adding“类定义的简洁语法”,例如我们在 C# 6.0 中“可以直接从构造函数声明”的属性。让我们希望这样的功能能够发光。

所以您的核心问题“为什么语言不将依赖注入作为核心集成?”,他们确实做到了。 Scala 和 F# 已经让这变得更容易了,C# 有望跟进。

与此同时,我试图通过在部分课程中为您编写T4 template that generates the constructor 来克服这个障碍,但是在应用程序中使用了几周后,它确实没有按预期工作。

【讨论】:

  • 啊至少有人看到了兴趣:)
  • 但这并不是真正的依赖注入,是吗? Anywho,Scala 通过使用构造函数参数对类进行参数化,优雅地解决了这个问题。
  • @Gustafc:例子展示了构造函数注入,这是依赖注入的一种特定形式(最常见的形式)。
【解决方案3】:

正如 Grodon 在 cmets 中所说:函数/方法参数是依赖注入 - 几乎所有语言都支持最低级别的参数。

DI 框架通常针对服务器环境量身定制。语言机制只是错误的抽象级别。

【讨论】:

  • “DI 框架通常是针对服务器环境量身定制的。”我不同意! DI 框架可以一直用于(并且正在使用)客户端应用程序,例如 Silverlight、Forms 和 WPF。
  • 我当然忘了提到 Windows 服务 :-)
【解决方案4】:

实际上,它们是通过让您将参数传递给方法/构造函数/函数来实现的——这几乎就是它的全部内容,DI 框架所做的只是一种指定参数值的奇特方式。

一个更有趣的问题是如何在语言级别强制依赖注入。禁止static 状态可能是一个好的开始(就像Newspeak 一样)。

【讨论】:

    【解决方案5】:

    这本质上是一种有缺陷的方法。理想情况下,语言应该尽可能精简,但要足够强大以引入任意语言级别的抽象(想想 LISP 和元编程)。如果不是,您在哪里划定要包含的内容和省略的内容?

    至于引入对 DI 的编译级支持,这是不可能的。您的应用程序可能会使用各种动态链接库,而这些库在编译时甚至可能不为人所知。想想插件。

    【讨论】:

      【解决方案6】:

      如果一种语言足够灵活,它可以模拟 DI。 Java 和 C# 显然不是,但函数式或混合语言通常是。例如。在 Haskell 中,您可以使用 Reader Monad 来保持“环境”而不会乱扔代码,或者您可以使用类型类。 Scala 具有 mixin 组合和隐式对象,它们都可以用于此目的。所以我会得出结论,真正需要 DI 的语言只是缺乏适当且强大的抽象机制。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        • 2018-12-14
        • 2018-01-03
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多