关于DI的问题以及如何解决一些问题

时间:2011-03-25 16:59:19

标签: c# oop dependency-injection spring.net domain-model

我是依赖注入的新手。我从来没有使用过,甚至从来都不知道它的外观是什么,但是在我对这个主题的最后一次攻击之后,我发现这是一种解耦对象及其依赖关系的方法,一旦它们不负责实例化它的具体版本依赖关系已经存在了,因为现在容器将为我们做这件事并将准备好的对象交付给我们。

现在重点是; “我什么时候应该使用它?”,总是???实际上,由于我是新手,甚至从未见过使用此模式的项目,我无法理解应该如何将其应用于我的域对象!在我看来,我永远不会实例化我的对象,容器将永远为我做,但后来有些怀疑......

1)oobjects的部分依赖关系来自UI,例如;

public class User(String name, IValidator validator)

假设我从用户名中获取了用户名,那么conatiner如何知道它并仍然为我开发这个对象?

2)我面临的另一种情况;如果一个依赖项现在是一个已经实例化的对象,比如说......一个SINGLETON对象。我看到有关注入依赖项的生活范围的有关设置(我正在谈论Spring.NET,例如; http请求范围)...... 但是,请求和其他与网络相关的事情都在我身上表示层,所以如何在不破坏任何设计规则的情况下链接我的表示层和我的域层(因为我的域应该完全不知道它被消耗在哪里,不具有层依赖性等)

我渴望听到你们所有人的意见。非常感谢。

3 个答案:

答案 0 :(得分:1)

1)这个构造函数可能不是正确使用的,可能是你在错误的地方/方式注入验证器。

2)Neighter View或Model和nor Controller应该知道有一个IoC,它应该位于后台架构中(MVC组件实际被实例化)

当您觉得架构变得复杂并且必须由许多人保留时,您应该使用IoC。如果您正在编写企业应用程序,或者您认为使用插件扩展的UI,则可能需要它,如果您正在编写命令行实用程序,可能不是。

答案 1 :(得分:1)

只要您需要以下任何好处,就应该使用依赖注入:

  • 轻松更换模块的能力
  • 在应用程序的各个部分或不同的应用程序之间重用模块的能力
  • 当你想进行并行开发时,系统的组件可以单独开发,并行开发,因为它们依赖于抽象
  • 当您因为松散耦合而希望更容易维护系统时
  • 当您需要可测试性(替换模块的专业化)时。这是使用DI
  • 的最大原因之一

回答您的其他问题:

1)您可以配置许多IoC容器,以便可以指定某些构造函数参数,而其他容器则可以解析其他参数。但是,您可能需要考虑重构该段代码,因为UserFactory可能更合适,它接受验证器依赖,并且具有NewUser方法,该方法接受用户名并返回新用户(直接实例化或从容器中解析)。

2)您构建的每个应用程序都将具有组合根,您的容器已配置,并且根对象已解析。因此,每个应用程序都有自己的IoC配置,因此应用程序类型和配置设置之间存在预期的链接。任何常见的抽象注册都可以放在配置代码中,可以在所有应用程序之间共享。

答案 2 :(得分:1)

一般情况下,一旦你进入IoC,你往往希望用IoC注册一切,并让容器吐出完全水合的物体。但是,你提出了一些有效的观点。

也许“依赖”的定义是有序的;在最广泛的情况下,依赖只是一组功能(接口),给定的类需要具体实现才能使类正常工作。因此,大多数非平凡的程序都充满了依赖性。为了便于维护,通常优选所有依赖性的松散耦合。但是,即使松散耦合,如果这些对象需要您不希望污染IoC注册表的专用信息,也不需要自动化依赖项的实例化。目标是松散地结合使用,而不一定是创造。

关于第1点,一些IoC框架在给出外部参数方面表现不佳。但是,您通常可以将委托注册为工厂方法。该委托可以属于像UI那样由UI提供外部信息的对象。登录是一个很好的例子:创建一个对象,比如一个LoginController,并将其作为ILoginController注册到IoC。您将在“登录”页面上引用该控制器,它将在实例化登录页面时被注入,并且登录页面将向其传递输入的凭据。然后,Controller将执行身份验证,并将生成一个生成User对象的GetAuthenticatedUser()方法。您可以将此方法与IoC一起注册为用户工厂,并且无论何时需要用户,工厂代表都将被评估或批量传递给依赖方法,该方法将在真正需要用户时调用它。

在第2点,设置对象的单个实例是IoC模式的优势。您可以使用私有实例构造函数,静态实例和静态构造函数来生成实例,而不是创建一个真正的单例,只需向IoC注册该类,并告诉它只实例化一次并将该实例用于所有请求。力量是灵活性;如果您以后希望有多个实例,则只需更改注册即可。你不会破坏任何设计模式规则;视图将始终注入一个控制器,无论该控制器对于所有页面是相同的还是每个请求都有一个新实例。