为什么 IOC 容器被认为是减少耦合的一种方式?
我正在考虑在我的项目中使用 DI 和 Unity。我有一个问题:它将如何减少耦合?从我的角度来看,它正在增加耦合,因为:
我需要创建 UnityContainer 并在那里注册所有类型。这意味着我需要引用创建此容器的程序集中的所有程序集。
IUnityContainer UnityContainer; //.... IUnityContainer UnityContainer= new UnityContainer(); UnityContainer.RegisterType
(); 我需要使用 Resolve 创建服务实例,但这意味着我需要使用容器引用程序集。
var service = SomeClassWithContainer.UnityContainer.Resolve
();
我是否误解了某些东西,或者实际上它正在增加耦合?
I am thinking about using of DI and Unity in my project. And I have a question: how it will reduce coupling? From my point of view, it is increasing of coupling, because:
I need to create UnityContainer and register all types there. It means that I need to have the reference to all assemblies in assembly where this container is created.
IUnityContainer UnityContainer; //.... IUnityContainer UnityContainer= new UnityContainer(); UnityContainer.RegisterType<IMyService, CustomerService>();
I need to create an instance of my service using Resolve but it means that I need to have the reference to assembly with container.
var service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
Have I misunderstood something or in reality it is increasing of coupling?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您误解了应该如何解决您的依赖关系。
1.) 仅在引导代码中需要引用 Unity,引导代码位于应用程序的单个中心位置。
2.) 一旦引导完成,所有依赖项(理想情况下)都将使用构造函数注入来解析,如果包含类是通过 Unity 解析的,则由 Unity 自动完成 - 它会向下滴入对象图。您使用的示例实际上只是“服务定位器”模式,而不是 DI。
这确实减少了耦合,因为您不是直接创建您的类所依赖的具体类,而是将依赖项(同样理想的是一些抽象,如接口)“注入”到您的类中,这允许您用其他类替换这些依赖项,即在单元测试场景中。
I think you misunderstood how your dependencies should be resolved.
1.) A reference to Unity should only be needed in your bootstrapping code which is at a single central spot in your application.
2.) Once bootstrapping is done all dependencies (ideally) are resolved using constructor injection which is automatically done by Unity if the containing class is resolved via Unity - it is trickling down the object graph. The example you use is really just the "service locator" pattern and not DI.
This does reduce coupling since instead of directly creating a concrete class your class depends on, you "inject" dependencies (again ideally some abstraction like an interface) into your class which allows you to substitute those dependencies with other classes i.e. in the unit testing scenario.
您的问题包含服务定位器反模式的示例:
由于信息流动的方向,这与依赖注入模式根本不同:在上面的示例中,您伸出援手并询问服务,而在下面的示例中,您将获得服务:
这种模式称为构造函数注入,它将
UsesMyService
类与周围基础设施的详细信息分离。现在,任何拥有IMyService
实现的人都可以创建UsesMyService
实例,而无需知道如何配置中央静态位置。他们怎么知道要配置什么?他们要么需要源代码,要么需要一些文档来告诉他们该类依赖于
IMyService
。构造函数参数清楚地向消费者表达了该要求,无需任何外部引用。如果您在整个库中遵循这种模式,则您将承担将对象一直组装到最外层(称为组合根)的责任。这个位置(通常是顶级应用程序类)是唯一引用您正在使用的所有库的位置。 这就是容器所在的位置,整个解决方案中的其他类都不需要引用它。
Your question contains an example of the Service Locator anti-pattern:
This is fundamentally different than the Dependency Injection pattern because of the direction the information flows: in the above example, you reach out and ask for the service, whereas in the example below, you are handed the service:
This pattern, known as constructor injection, decouples the
UsesMyService
class from details about the surrounding infrastructure. Now, anyone with an implementation ofIMyService
can create instances ofUsesMyService
without having to know to configure a central static location.How would they even know what to configure? They would either need the source code or some documentation telling them that the class depends on
IMyService
. The constructor parameter cleanly expresses that requirement to consumers without any external reference.If you follow this pattern throughout your libraries, you bubble the responsibility of assembling the objects all the way to the outermost layer, known as the Composition Root. This single location, usually the top-level application class, is the only place with references to all of the libraries you are using. That is where the container lives, and no other class in your entire solution needs to reference it.