如何在企业项目中使用依赖注入

Mar*_*tus 3 c# architecture dependency-injection inversion-of-control

想象一下,你有一个应用程序,有数百个类实现了几十个"高级"接口(意味着组件级别).是否有推荐的依赖注射方式(如团结).是否应该有一个可以用于自举的"通用容器",可以作为Singleton访问?是否应该传递一个容器,所有实例都可以在RegisterInstance中传递?应该在启动时的某个地方通过RegisterType完成所有事情吗?如何在需要时使容器可以访问.构造函数注入似乎是错误的,作为标准方式的争论,您必须将接口从组件级别传递到在启动时使用它的非常低的位置,或者引用最终在"知道您居住的地方"反模式.而且:拥有一个"可用"的容器可能会让开发人员想到在客户端上下文中解析服务器组件.怎么避免呢?

欢迎任何讨论!


编辑澄清

我想出了一个有点真实世界的例子,可以更好地了解我看到的问题.

让我们想象一下应用程序是一个高保真系统.该系统具有CD播放器(集成在CD机架中)和USB端口(集成在USB机架中)以播放音乐.

现在,CD播放器和USB端口应能播放mp3音乐.

我周围有一个mp3解码器,可以注射.

现在我开始使用高保真系统.还没有插入CD,也没有插入usb棒.我现在不需要mp3解码器.

但是使用构造函数注入,我必须已经将依赖注入cd机架和USB机架.

如果我从不插入MP3 CD或MP3 usb棒怎么办?

我应该在CD机架中保留一个参考,所以当插入一张mp3光盘时,我手头有一个装饰器吗?(对我来说似乎不对)

cd机架的子系统需要解码器,只有在插入mp3时才会启动解码器.现在我在CD机架上没有容器,这里的构造函数注入怎么样?

Jup*_*aol 6

首先,依赖注入是一种不需要容器的设计模式.DI模式表明:

依赖注入是一种软件设计模式,允许在运行时而不是编译时选择组件

以Guice(java依赖注入框架)为例,在Java中Guice是一个DI框架,但它本身不是容器.

.Net中的大多数DI工具实际上都是容器,因此您需要填充容器以便能够注入依赖项

我不喜欢每次在容器中注册每个组件的想法,我只是讨厌这个.有几个工具可以帮助您根据约定自动注册组件,我不使用Unity,但我可以举例说明NinjectAutoFac

我实际上正在使用几乎任何DI工具基于惯例编写一个小型实用程序来自动注册组件,它仍处于开发阶段

关于你的问题:

是否应该有一个可以用于自举的"通用容器",可以作为Singleton访问?

答案是肯定的(有一个工具来抽象使用的DI工具,它被称为ServiceLocator)DI工具是如何工作的,有一个静态容器可用于应用程序,但是,不建议在域对象中使用它创建实例,这被认为是一种反模式

BTW我发现这个工具在运行时注册组件非常有用:

http://bootstrapper.codeplex.com/

是否应该传递一个容器,所有实例都可以在RegisterInstance中传递?

否则会违反得墨忒耳法律.如果决定使用容器,最好在应用程序启动时注册组件

如何在需要时使容器可以访问

使用Common Service Locator你可以在你的应用程序的任何地方使用它,但就像我说的,不建议在域对象中使用它来创建所需的实例,而是在对象的构造函数中注入对象并让DI工具自动注入正确的实例.

现在基于此:

构造函数注入似乎是错误的,作为标准方式的争论,您必须将接口从组件级别传递到在启动时使用它的非常低的位置,或者引用最终在"知道您居住的地方"反模式

让我觉得你没有为你的应用程序大量编写单元测试,这很糟糕.所以我的建议是,在选择您要使用的DI工具之前,或者在考虑所有答案之前,请考虑以下问题,请参考以下链接,重点关注一件事:编写干净的可测试代码,这是到目前为止,您可以自己回答问题的最佳来源

清洁代码谈判:

用品

强烈推荐以下链接

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html