C# 我是否可以在单层中注册所有IoC容器组件,或者在使用的每一层中注册所有IoC容器组件?
我正在使用Unity IoC框架,在我的主机MVC层中有一个C# 我是否可以在单层中注册所有IoC容器组件,或者在使用的每一层中注册所有IoC容器组件?,c#,inversion-of-control,unity-container,C#,Inversion Of Control,Unity Container,我正在使用Unity IoC框架,在我的主机MVC层中有一个Bootstrapper.cs类来注册所有组件。然而,在我的体系结构中,我在MVC层下面有一个“服务”层,它也使用DI,并向其中注入了存储库接口(存储库接口不在MVC层中使用-它将服务层接口注入其控制器) 因此,我的问题是:我是否仍然可以在整个应用程序的MVC/UI层中将存储库接口注册到它的具体类型,或者我是否可以添加对Unity的另一个引用,并在我的“服务”层中创建另一个Bootstrapper.cs类来定义该特定层使用的接口类型 即
Bootstrapper.cs
类来注册所有组件。然而,在我的体系结构中,我在MVC层下面有一个“服务”层,它也使用DI,并向其中注入了存储库接口(存储库接口不在MVC层中使用-它将服务层接口注入其控制器)
因此,我的问题是:我是否仍然可以在整个应用程序的MVC/UI层中将存储库接口注册到它的具体类型,或者我是否可以添加对Unity的另一个引用,并在我的“服务”层中创建另一个Bootstrapper.cs
类来定义该特定层使用的接口类型
即使答案是我可以在UI层注册接口,我还是想知道常见的做法。我不喜欢在MVC/UI层中注册该类型,因为我必须添加对存储库层的引用才能进行注册,即使我知道它没有在该层中使用。它用于服务层
谢谢 简言之,是的,可以将配置保持在流程顶部或定位到每个模块。但是,必须为流程中的整个对象图解析所有依赖关系
通过将配置保存在每个模块(程序集)中来本地化配置通常是一个好主意,因为您允许您的服务层负责自己的配置。我的回答是,IMHO,这是一个很好的做法。我把你的问题抛到脑后 如果在类库中添加对Unity的引用,则会将依赖项添加到正在使用的框架中。这与你想要达到的目标完全相反 您的类需要的唯一调整是支持构造函数或在接口上使用公共属性。就这样 因此,应用程序入口点应该完成所有的“引导”。 注意,入口点可以是不同的应用程序,也可以是不同的测试项目。它们可以有不同的配置和模拟场景 如果bootstrap.cs变大,出于可读性原因,可以将其拆分为更小的部分。但是我拒绝让类知道它们正在被引导/moqed/注入以及被什么东西注入的事实
考虑重复使用。您当前的库正在使用Unity。它们可以在使用StructureMap的项目中使用。或者为什么不使用Ninject。每个应用程序都应该有自己的合成根,即配置应用程序的位置() 这取决于上下文,但一般来说,如果您将容器配置拆分到各个层中,那么您将对层的配置做出决定,因为这些层太接近这些层,您很可能会失去总体视图 例如,在您的一个业务逻辑层中,您正在注册一个服务:
container.RegisterType<ISercice1, MyImplementation1>(new PerThreadLifetime())
container.RegisterType(新PerThreadLifetime())
但当在web应用程序中使用该层时,您可以决定PerSession或PerRequest生命周期将是更好的生命周期。这个决定应该只在一个地方,而不是通过层传播。是的,应用程序应该在入口点有一个合成根。但是,将类的注册保存在实现它们的层中是一种很好的做法。然后从合成根的层中提取这些注册,逐层注册实现。这就是为什么:
请参阅使用工作示例更详细地说明这些要点。如果在UI中这样做,则意味着您必须在UI中引用服务实现,我认为您不希望这样做。另外,当您想要在服务和存储库层之间进行集成测试时,您需要注册DI,因此如果您在UI中这样做,那么集成测试将如何工作?谢谢-我在链接中查看了您的答案,但我没有完全理解(不是您的错)。你知道有什么扩展的例子可以帮助我吗?我不确定有没有扩展的例子。你不确定的是什么?事实上我读了更多的例子,现在就明白了。仍然只有一个组合根,对吗?只是安装程序指定了特定于该层的依赖项,对吗?是的,组合根必须是调用的入口点(对象)。为了映射下面的对象图,必须解决这个问题。自从那个例子使用Windsor,我使用Unity创建安装程序类以来,有什么想法吗?