依赖注入框架会导致糟糕/懒惰的设计吗?

时间:2009-02-05 19:52:57

标签: dependency-injection

我对DI概念相当新,但我在设计中已经在某种程度上使用它 - 主要是通过将'接口'接入构造函数并让工厂创建我的具体类。好吧,它不是基于配置的 - 但它永远不需要。

我开始研究诸如Spring.NET和Castle Windsor之类的DI框架,并偶然发现了Ayende的blog

我从中得到的是

A)DI框架很棒,但是 B)这意味着我们不必担心我们的系统是如何根据依赖性设计的。

对我来说,我过去常常想过如何松散地耦合我的系统,但同时对依赖关系进行某种控制。

我有点害怕失去这种控制,它只是一个免费的。 ClassA需要ClassB =没问题,只要问,你就收到了!嗯。

或者只是重点,这就是未来,我应该选择它吗?

思想?

8 个答案:

答案 0 :(得分:9)

一个基本的OO原则是您希望您的代码依赖于接口而不是实现,DI就是我们这样做的方式。从历史上看,这是它的演变过程:

  1. 人们最初通过“新”来创造他们所依赖的课程:

    IMyClass myClass = new MyClass();

  2. 然后我们想删除实例化,因此有静态方法来创建它们:

    IMyClass myClass = MyClass.Create();

  3. 然后我们不再依赖于类的生命周期,但仍然依赖它进行实例化,因此我们使用了工厂:

    IMyClass myClass = MyClassFactory.Create();

  4. 这将直接依赖于消费代码转移到工厂,但我们仍然间接依赖MyClass,所以我们使用了这样的服务定位器模式:

    IMyClass myClass =(IMyClass)Context.Find(“MyClass”);

  5. 这样我们只依赖于代码中的接口和类的名称。但它可以做得更好,为什么不简单地依赖于我们代码中的接口?我们可以依赖注入。如果使用属性注入,则只需在代码中为所需的接口添加属性setter。然后,配置实际依赖项在代码之外的内容,容器管理该类和类的生命周期。

答案 1 :(得分:7)

我不会说你不必考虑依赖关系,但是使用IoC框架可以让你很少或没有麻烦地改变满足依赖关系的类型,因为所有的连线都是在一个中心位置完成的。

你仍然需要考虑你需要什么样的接口并且正确地使用它们并不总是一件小事。

我看不出松散耦合的系统如何被认为是懒惰的设计。如果您经历了了解IoC框架的所有麻烦,那么您肯定不会采用这种捷径。

答案 2 :(得分:3)

我认为理想情况下,如果你已经有一个loosley耦合系统..,使用容器只会移动你从代码中取出依赖项的地方,使它们更柔和,让你的系统依赖于容器构建你的对象曲线图。

实际上,尝试使用容器可能会向您显示您的系统并不像您想象的那样松散耦合..所以这样,它可以帮助您创建更好的设计。

嗯,我是这个子喷气机的新手......所以也许我不是那么正确。

干杯。

答案 3 :(得分:1)

我必须高,因为我认为依赖注入的全部意义在于,执行内容的代码只是声明其依赖关系,以便创建它的人知道要用它创建什么才能使其正常运行。

依赖注入如何让你变得懒惰可能会迫使其他人处理依赖关系? 这就是重点!其他人不需要真正成为别人;它只是意味着您编写的代码不需要关注依赖项,因为它预先声明它们。而且它们可以被管理,因为它们是明确的。

编辑:添加了上面的最后一句话。

答案 4 :(得分:1)

依赖注入可能有点难以习惯 - 而不是通过代码的直接路径,您最终会看到看似未连接的对象,并且给定的操作会跟踪它通过一系列这些对象的路径,这些对象的耦合看起来如此,善良,抽象。

这是一种类似于习惯OO的范式转换。目的是编写对象确实具有集中和单一的责任,使用依赖对象,因为它们由接口声明并由框架处理。

这不仅使松散耦合变得更容易,而且几乎不可避免,或者至少差不多,这使得在模拟环境中运行对象变得更加简单 - IOC容器取代了运行环境。

答案 5 :(得分:1)

我不同意并说它们在许多情况下会带来更好的设计。通常开发人员创建的组件过多且依赖性太大。对于IOC开发人员,我发现他们倾向于转向更好的思维方式,并生成更小的更简单的组件,这些组件可以组合到一个app.s

如果他们遵循精神并进行测试,他们将进一步优化您的组件。这两个练习都迫使您编写更好的可测试的组件,这些组件非常适合IOC容器的工作方式。

答案 6 :(得分:0)

你还是要担心。我的团队在我们当前的项目中使用Castle Windsor。令我很生气的是它将依赖查找从编译时延迟到运行时。

如果没有Castle Windsor,您可以编写代码,如果您尚未对依赖项进行排序。邦,编译器会抱怨。使用Castle Windsor,您可以在xml文件中配置依赖项。他们仍然存在,只是从大部分代码中分离出来。问题是,如果你搞定了依赖关系,你的代码可以正常编译。但是,在运行时,Castle Windsor通过使用反射查找具体的类来为接口提供服务请求。如果找不到依赖项,则会在运行时收到错误。

我认为Castle Windsor会在初始化时检查依赖项是否存在,以便它可以非常快速地抛出错误。但是,当使用强类型语言时,在运行时无法解决这个问题仍然很烦人。

所以......无论如何。依赖性仍然严重。你们所有人都会比以前更加注意使用DI。

答案 7 :(得分:0)

我们编写了自定义DI框架,认为花了一些时间才能做到正确,但这一切都值得付出努力。我们已将who系统划分为多个层,每个层中的依赖注入受规则约束。例如。在Log层中,不能注入CUD和BO接口。

我们仍在考虑规则,其中一些规则每周都会改变,而其他规则保持不变。