我正在使用IoC容器来注册和解析类型。
我有以下项目:
项目A
ClassA的 - SubClass1 - SubClass2
ProjectB(类库)
ClassB的 - SubClass3 - SubClass4
ProjcetA正在使用ProjectB。
ProjectA是应用程序的入口点。
ProjectA不了解SubClasses3和SubClass4。
我为ProjectA和ProjectB提供了单独的单元测试项目。
由于我不希望ProjectA了解SubClasses3和4,在类库中注册类型的正确方法是什么?
我应该将IoC容器从ProjectA传递给B还是使用两个IoC容器?
我的问题不是如何使图书馆DI不可知/非迪 可用。我的问题是注册孩子时的最佳做法是什么 类库中的依赖项。
答案 0 :(得分:1)
我的问题是在类库中注册子依赖项时的最佳实践。
我不希望ProjectA了解SubClasses3和4
见Ioc/DI - Why do I have to reference all layers/assemblies in entry application?。
如果您遵循DI模式,您的类库将不会有“子依赖项”。相反,依赖关系将完全(除了可能的一些抽象库)与启动应用程序中的组合根减少为1对1的关系。
ProjectA
应用程序理想依赖于SubClasses 3 and 4
。如果SubClasses 3 and 4
依赖于彼此或其他库中的组件,则在使用SubClass 3
或SubClass 4
时会拖动额外的依赖项。
相反,将所有耦合代码放在合成根中,将无耦合代码放在应用程序层类库中。这使应用程序负责其所有依赖项。
如果您有其他类型的类库,例如可重用的应用程序组件,则可以使用一些技术来耦合它们,但允许它们仍然是可注入的。请参阅DI-Friendly Library和DI-Friendly Framework。
注意:将所有耦合代码放在合成根中并不一定意味着您必须将它们全部放在同一个方法或类中。您可以跨多个类组织它和/或使用Ian's answer中的约定来使其可维护。但是在一天结束时,应用程序应该负责其依赖项,因此您不应将此代码移动到其他应用程序层中 - 将其保留在应用程序的启动层中。
答案 1 :(得分:1)
项目B不需要了解您的IoC容器。如果你很快采用这种方法,你所有的DLL都依赖于某个特定的IoC库。
在Autofac中,您可以执行以下操作:
builder.RegisterAssemblyTypes(typeof(ClassB).Assembly)
.Where(x => typeof (ISomeInterface).IsAssignableFrom(x))
.AsImplementedInterfaces();
这里我正在注册从另一个DLL实现特定接口的所有内容。我对该程序集中的任何类都没有直接依赖关系,它们被声明为internal
来强制执行。对于单元测试,我的测试项目使用[InternalsVisibleTo]来直接实例化类,但不将它们公开为公开。