关于SOLID原则,DI使用容器和Unity:如何管理容器中的DI映射?

About SOLID principles, DI using containers and Unity: How to manage the DI mapping in the container?

好的。我终于理解了 DI 甚至 IoC、容器等等所有那些复杂的概念。但是我仍然缺少一些东西。

假设我有一个名为 SomeClass 的 class,它将在他的构造函数中实例化实现 IFirstLevelOfAbstraction 的 class 之一。实现 IFirstLevelOfAbstraction 的 classes 是 SubClass1SubClass2。我提到的那些 classes 实例化了一个 class 实现 ISecondLevelOfAbstraction,它们是 SubClass3SubClass4.

TL;DR 这是图片。

在我的入口点使用 unity 这应该看起来像这样:

IUnityContainer container = new UnityContainer();
container.RegisterType<SomeClass>();
container.RegisterType<IFirstLevelOfAbstraction, SubClass1>();
container.RegisterType<IFirstLevelOfAbstraction, SubClass2>();
container.RegisterType<ISecondLevelOfAbstraction, SubClass3>();
container.RegisterType<ISecondLevelOfAbstraction, SubClass4>();
var someClass= container.Resolve<SomeClass>();

问题是:我如何选择DI在容器中的路径?

IFirstLevelOfAbstraction 的实例是 SubClass1ISecondLevelOfAbstraction 的实例是 SubClass4.

以后如何轻松更改它?

嵌套这么多 DI 不是反模式吗?为什么?为什么这有什么好处?

感觉没人用这个。它甚至不是 C# 中的原生语言。

一种方法是不注册SubClass1SubClass2SubClass3SubClass4,然后在解析时选择此类依赖项。这是一个例子:

IUnityContainer container = new UnityContainer();

var someClass = container.Resolve<SomeClass>(
    new DependencyOverride<IFirstLevelOfAbstraction>(new ResolvedParameter<SubClass1>()),
    new DependencyOverride<ISecondLevelOfAbstraction>(new ResolvedParameter<SubClass4>()));

如果这不是您的选择(您不想在解析时指定任何内容),则需要使用 named registrations。不过我不建议走那条路。

由于单个接口有多个实现,我建议您使用 Pure DI. See my article here 是有原因的。

以下是您的代码使用 Pure DI 时的样子:

var someClass =
    new SomeClass(
        new SubClass1(
            new SubClass4()));