使用依赖注入时如何避免循环依赖? [英] How to avoid Cyclic Dependencies when using Dependency Injection?

查看:598
本文介绍了使用依赖注入时如何避免循环依赖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对概念依赖注入还比较陌生,因此我不确定它如何防止循环依赖。假设我关注了项目(示例项目结构可能不好,但请忍受)

I am relatively new to the concept dependency injection, so I am unsure about how it prevents cyclic dependencies. Let's say I have followed projects (the sample project structure might not be good but please bear with me)


项目A:

Project A:


  • 域层

  • IRepository

项目B:


  • RepositoryImpl->实现IRepository接口

在这种情况下,项目B将需要引用项目A。但是要设置项目A,让我们例如Unity容器,项目A将需要引用项目B,以便在Unity Config中具有类似的内容。

In this case Project B will need to reference Project A. But to set up Project A, let's say Unity Container, Project A will need to reference Project B in order to have something like this in the Unity Config.

container.RegisterType<IRepository, Repository>();

但这不会引入循环依赖性吗?还是我对依赖注入或循环依赖有错误的理解?甚至是两者?

But doesn't this introduce cyclic dependency? Or is it I'm having wrong understanding in either Dependency Injection or cyclic Dependency? or even both?

推荐答案

您在这里缺少一个重要的概念,即合成根的概念。关于组成根的最佳和最详尽的描述可以在此处。总结一下:

You are missing an important concept here, which is the concept of the Composition Root. The best and most elaborate description of what a Composition Root is, can be found here. To summarize:


组合根是应用程序中模块组成在一起的(最好)唯一位置。

A Composition Root is a (preferably) unique location in an application where modules are composed together.

如文章所述:


大多数类使用构造函数注入。通过这样做,他们将创建依赖关系的责任推给了消费者。那个消费者也再次提高了创建依赖项的责任。

Most classes use Constructor Injection. By doing this they push the responsibility of the creation of their dependencies up to their consumer. That consumer -again- push the responsibility of the creation of its dependencies up as well.

我们不能无限期地延迟创建类的时间。我们必须在某个位置创建对象图。您应该将创建的内容集中到应用程序的单个区域中。这个地方称为合成根

We can’t delay the creation of our classes indefinitely. There must be a location where we create our object graphs. You should concentrate this creation into a single area of your application. This place is called the Composition Root.

仅应用程序的入口点包含合成根,任何其他

Only the application's entry point contains a Composition Root, any other libraries in application do not.

这意味着应用程序 域层不会将其类型注册到DI中容器-只有启动项目才能执行此操作。因此,当您执行此操作时,域层将不必必须依赖数据访问库(您的项目B)。

This means that the Domain Layer itself does not register its types into the DI Container—only the startup project does this. When you do this, the Domain Layer will therefore not have to depend the Data Access Library (your Project B).

第一版版本(第2章)和第二版(第3章)详细讨论了一个示例,该示例非常接近问题中给出的应用程序结构。先前引用的《合成根目录》文章摘自第二版。可以免费在线。

Both the first edition (chapter 2) and second edition (chapter 3) of the book Dependency Injection in .NET contain a elaborate discussion of an example that is very close to the application structure given in your question. The previously referenced Composition Root article is an excerpt from the second edition. The first chapter can be read for free online.

这篇关于使用依赖注入时如何避免循环依赖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆