使用依赖注入时如何避免循环依赖?

How to avoid Cyclic Dependencies when using Dependency Injection?

我对依赖注入这个概念比较陌生,所以我不确定它是如何防止循环依赖的。假设我已经关注了项目(示例项目结构可能不太好,但请耐心等待)

Project A:

  • Domain Layer
  • IRepository

Project B:

  • RepositoryImpl --> implement IRepository interface

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

container.RegisterType<IRepository, Repository>();

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

您在这里遗漏了一个重要的概念,即复合根的概念。可以在 here 中找到关于组合根是什么的最好和最详尽的描述。总结:

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.

只有应用程序的入口点包含组合根,应用程序中的任何其他库

这意味着域层 本身 不会将其类型注册到 DI 容器中——只有启动项目会这样做。当您执行此操作时,域层将因此 而不是 必须依赖数据访问库(您的项目 B)。

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.