2011-03-25 126 views
2

我是依赖注入的新手。我从来没有使用过,甚至从来没有体会过它的所有特征,但是在我最后一次攻击这个主题后,我发现这是一种解耦对象及其依赖的方式,一旦它们不负责实例化它的具体版本现在,容器会为我们做这件事,并把我们手中的准备好的东西传递出去。关于DI的问题以及如何解决一些问题

现在的重点是; “我应该什么时候使用它?”,总是?其实,因为我是一个新手,甚至从来没有看到过使用这种模式的项目,所以我不知道该如何将它应用到我的域对象中!在我看来,我将永不再实例化我的对象和容器将永远为我做的,但后来谈到有些疑惑...

1)约oobjects其依赖的那部分是什么来自UI,例如;

public class User(String name, IValidator validator) 

假设我从用户界面获取用户名,那么conatiner如何知道它,并仍然为我描述这个对象?

2)Theres other situation I'm facing;如果依赖项现在是一个已经实例化的对象,比如说......一个SINGLETON对象。我看到了关于注入依赖注入的生命周期的设置(我在谈论Spring.NET,例如http请求范围)... 但是,请求和其他web相关的东西在我的表示层上,所以如何我可以在不违反任何设计规则的情况下链接我的表示层和我的域图层(因为我的域应该完全不知道它正在被使用的位置,不具有图层依赖性等)

我渴望听到您的消息。非常感谢。

+1

很多DI问题今天=)看看这个答案是否有帮助。 :http://stackoverflow.com/questions/5433211/difference-between-ninject-and-rhinomock-or-moq/5433231#5433231 – gideon 2011-03-25 17:07:07

+0

它有用@giddy,谢谢,但不完全是重点! =) – renatoargh 2011-03-25 17:11:08

+0

@Renato只是认为这将有助于解释_如何使用DI。 =) – gideon 2011-03-25 17:12:57

回答

1

一般来说,一旦你去了IoC,你往往希望用IoC注册一切,并让容器吐出充满水分的物体。但是,您提出了一些有效的观点。

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

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

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

1

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

2)Neighter查看,也没有型号和NOR控制器应该知道的有一个IoC,它应当处于在后台架构(如MVC组件被实例化)

当你感到架构,您应该使用的IoC可能会变得复杂,并且必须被许多人所使用。如果您正在编写企业应用程序,或者您认为要使用插件进行扩展的用户界面,则可能需要它,如果您正在编写命令行实用程序,则可能不需要。

1

你应该使用依赖注入,只要你想要的任何的下列优点:

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

为了回答您的其他问题:

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

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