我理解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?
答案 0 :(得分:4)
我不应再使用新关键字
了
关于the differences between newables and injectables的全部内容。是的,您绝对应该仍然使用new关键字,但不能使用服务/注射。
他是否意味着唯一一次应该调用DI框架(to 解决问题)是从应用程序的开始
您需要解决一次每个请求。如果您的应用程序处理单个请求并且死亡(例如控制台应用程序),这意味着您在启动期间解决一次。然而,大多数应用程序类型(Web应用程序,Web服务,桌面应用程序等)处理许多请求(有时是并发),这意味着将解析许多“根”对象。
根据请求执行解析(无论“请求”可能位于该应用程序的上下文中)非常重要,因为为完整的应用程序域执行单个解析将创建单个对象图,这意味着此对象图应该是线程安全和可重用。你可能能够使这个工作,但这通常是很多工作和容易出错。这就是为什么DI容器通常包含注册具有特定范围的服务的复杂方法(每个Web请求,每个WCF操作等)。
DI是否意味着代码组织的特殊结构?
不,它没有。 DI不会强迫您进入某个组织结构,但您必须使用loose coupling和SOLID来设计类以获得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.html和http://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,特别是那里给出的演练。