为什么语言不把依赖注入作为核心?
本文关键字:核心 注入 依赖 语言 为什么 | 更新日期: 2023-09-27 17:50:23
既然依赖在复杂性理论中是万恶之源,为什么语言不把依赖注入集成到它们的核心(可能是在最低层次:编译)?这将避免使用框架。
我的目标是编译语言。
我的问题类似于最近在。net动态中引入的duck类型。为什么将来不为DI提供类似的东西呢?
因为语言是与设计/设计模式无关的
我个人可以看到这样做的好处。例如,我一直在写这样的代码:
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#团队可能会在c# 6.0中添加"类定义的简洁语法",比如"可以直接从构造函数声明"的属性。让我们希望这样的功能能带来光明。
所以你的核心问题"为什么语言不在核心中集成依赖注入?"Scala和f#已经让这变得更容易了,c#有望紧随其后。
与此同时,我试图通过编写一个T4模板来克服这个障碍,该模板在部分类中为您生成构造函数,但在应用程序中使用此模板几周后,它确实没有像预期的那样工作。
正如Grodon在评论中所说:函数/方法参数是依赖注入——几乎所有语言都支持最低级别的依赖注入。
DI框架通常是针对服务器环境量身定制的。语言机制只是一个错误的抽象层次。实际上,它们允许您将参数传递给方法/构造函数/函数-这几乎就是它的全部,DI框架所做的只是指定参数值的一种奇特方式。
一个更有趣的问题是如何在语言级别上强制依赖注入。禁止static
邦可能是一个好的开始(就像Newspeak做的那样)。
这本身就是一种有缺陷的方法。理想情况下,语言应该尽可能精简,但又足够强大,可以引入任意语言级别的抽象(想想LISP和元编程)。如果没有,你该如何区分该包含什么和不该包含什么?
至于引入对DI的编译级支持,那是不可能的。您的应用程序可能使用各种动态链接的库,这些库甚至可能在编译时都不知道。认为插件。
如果一种语言足够灵活,它可以模拟 DI。Java和c#显然不是,但函数式语言或混合语言通常是。例如,在Haskell中,你可以使用Reader Monad来保存一个"环境",而不会弄乱你的代码,或者你可以使用类型类。Scala有混合组合和隐式对象,它们都可以用于此。因此,我得出的结论是,真正需要 DI的语言只是缺乏适当而强大的抽象机制。