关于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 是 SubClass1
和 SubClass2
。我提到的那些 classes 实例化了一个 class 实现 ISecondLevelOfAbstraction
,它们是 SubClass3
和 SubClass4
.
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
的实例是 SubClass1
而 ISecondLevelOfAbstraction
的实例是 SubClass4
.
以后如何轻松更改它?
嵌套这么多 DI 不是反模式吗?为什么?为什么这有什么好处?
感觉没人用这个。它甚至不是 C# 中的原生语言。
一种方法是不注册SubClass1
、SubClass2
、SubClass3
或SubClass4
,然后在解析时选择此类依赖项。这是一个例子:
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()));
好的。我终于理解了 DI 甚至 IoC、容器等等所有那些复杂的概念。但是我仍然缺少一些东西。
假设我有一个名为 SomeClass
的 class,它将在他的构造函数中实例化实现 IFirstLevelOfAbstraction
的 class 之一。实现 IFirstLevelOfAbstraction
的 classes 是 SubClass1
和 SubClass2
。我提到的那些 classes 实例化了一个 class 实现 ISecondLevelOfAbstraction
,它们是 SubClass3
和 SubClass4
.
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
的实例是 SubClass1
而 ISecondLevelOfAbstraction
的实例是 SubClass4
.
以后如何轻松更改它?
嵌套这么多 DI 不是反模式吗?为什么?为什么这有什么好处?
感觉没人用这个。它甚至不是 C# 中的原生语言。
一种方法是不注册SubClass1
、SubClass2
、SubClass3
或SubClass4
,然后在解析时选择此类依赖项。这是一个例子:
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()));