关于DI / IoC的区域不明确

时间:2013-08-14 14:59:28

标签: architecture dependency-injection inversion-of-control organization

我理解IoC的基本概念,但我很难将我的视野扩展到最初的概念之外。


基本上,使用DI框架,我不应再使用具有依赖关系的对象的new关键字,因为那样,我不会调用DI框架解析方法,因此不会触发解析链。

  

用户想要一个对象A谁需要一个对象B谁想要一个对象C谁   希望...

这就是使用DI框架会发生的事情。但是使用new关键字,我会留下:

  

我只是实例化一个对象A

问题1:我是对的吗?错了吗?或者又是“依赖”的情况?


我刚读了Mark Seemann的答案(https://stackoverflow.com/a/2490797/2671072),他说:

  

DI容器应该解析整个依赖图   应用程序的组成Root并且不用了。

问题2:他是否暗示唯一一次应该调用DI框架(解决某些问题)是从应用程序的开始,从那里,一切都应该没问题,单独留下?


我正在开展一个项目。但是我很难定义接口和类(实体,值对象,实现)应该去哪里(程序集,命名空间命名......)。

问题3:DI是否意味着代码组织的特殊结构?


我听说域/业务层不应该引用任何DI框架。

问题4:该建议是否也适用于任何其他层?还是假的?


我正在使用两个库(比如LibraryA和LibraryB)。 LibraryB包含三个类,ClassA,ClassB,ClassC。每个类都依赖于前一个(ClassA是根/聚合)。 LibraryA依赖于ClassA。

问题5:在LibraryB中创建工厂是否更好,专门创建ClassA及其依赖项(仅使用new关键字),或者更好地充分利用DI框架,并手动注册ClassA,ClassB,ClassC和解决ClassA?

2 个答案:

答案 0 :(得分:4)

  

我不应再使用新关键字

关于the differences between newables and injectables的全部内容。是的,您绝对应该仍然使用new关键字,但不能使用服务/注射。

  

他是否意味着唯一一次应该调用DI框架(to   解决问题)是从应用程序的开始

您需要解决一次每个请求。如果您的应用程序处理单个请求并且死亡(例如控制台应用程序),这意味着您在启动期间解决一次。然而,大多数应用程序类型(Web应用程序,Web服务,桌面应用程序等)处理许多请求(有时是并发),这意味着将解析许多“根”对象。

根据请求执行解析(无论“请求”可能位于该应用程序的上下文中)非常重要,因为为完整的应用程序域执行单个解析将创建单个对象图,这意味着此对象图应该是线程安全和可重用。你可能能够使这个工作,但这通常是很多工作和容易出错。这就是为什么DI容器通常包含注册具有特定范围的服务的复杂方法(每个Web请求,每个WCF操作等)。

  

DI是否意味着代码组织的特殊结构?

不,它没有。 DI不会强迫您进入某个组织结构,但您必须使用loose couplingSOLID来设计类以获得the most benefit

  

我听说域/业务层不应该引用任何DI框架。   该建议是否也适用于任何其他层?还是假的?

是的,除了Composition Root之外,此建议适用于系统的每个部分。但请注意,图层不等于装配。看看this question and its answers

  

在LibraryB中创建工厂是否更好

没有更多信息就很难回答(你可能想为此开始一个新问题),但一般来说,你应该只为每个请求解析一个对象并让容器构建整个图形。如果LibraryA在LibraryB中使用ClassA,则LibraryA中将有一个或多个依赖于ClassA的类。因此,不应直接从容器中解析ClassA,而应该从容器中解析其中一个LibraryA类 - 或者递归地解析其父类之一。例如,如果你的MVC应用程序的XController依赖于依赖于ClassA的ClassD(来自LibA),那么你应该只解析XController。

答案 1 :(得分:2)

完全同意史蒂文的回答,以及关于你的第四个问题:

  

问题4:该建议是否也适用于任何其他层?   还是假的?

在域驱动设计中,域层被视为应用程序的核心,其他层(如UI,数据库,基础架构层)就像是它的附加组件。这就是为什么Domain层将成为主要层而没有引用其他层的原因。我希望这是他们上述陈述的意思。请查看问题DDD: how the layers should be organized?给出的图表。

为了进一步阅读,我有a post on DI here

如有进一步询问,请告诉我。感谢。

大卫的第一条评论答案:

Data Repositorys图层具有http://martinfowler.com/eaaCatalog/repository.htmlhttp://msdn.microsoft.com/en-us/library/ff649690.aspx的存储库。

映射层应该具有像Nhibernate或实体框架一样的ORM(http://en.wikipedia.org/wiki/Object-relational_mapping)。

Data Repository and Mapping是DAL(数据访问层)的一部分,它们是可选模式,但最常用于访问数据。如果你没有复杂的DAL ......你可以在这里使用JDBC或ADO.NE。

进一步了解DI如何在代码中工作...我找到的最佳位置是Ninject用户指南http://ninject.codeplex.com/wikipage?title=User%20Guide&referringTitle=Home,特别是那里给出的演练。