[英]IOC without Service Locator
Suppose I have 3 classes, Program
, A
(with dependencies D1
and D2
) and B
(with dependencies D3
and D4
). 假设我有3个类, Program
, A
(具有依赖项D1
和D2
)和B
(具有依赖项D3
和D4
)。 Program
initialises an IOC container and registers a bunch of types before creating an instance of A
. Program
在创建A
实例之前初始化IOC容器并注册一堆类型。
class Program
{
static void Main(string[] args)
{
IOC ioc = new IOC();
//register types
A a = ioc.Resolve<A>();
}
}
At some point later on, a
needs to create an instance of B
, injecting its two dependencies into the constructor. 稍后, a
需要创建一个B
实例,将其两个依赖项注入到构造函数中。
Question: How should a
resolve the dependencies of B
? 问:应该怎样a
解决的依赖性B
? I have been led to believe that passing the IOC container around ie injecting it into A
is the Service Locator pattern, which is bad. 我一直被认为相信,将IOC容器传递到周围(即,将其注入A
是Service Locator模式,这很糟糕。 If B
created C
with its dependencies, B
would also need to have the container injected, and the container would be littered throughout my code. 如果B
使用其依赖关系创建了C
,则B
也需要注入容器,并且该容器会在我的整个代码中乱扔垃圾。 This sounds like a testing nightmare. 这听起来像一场噩梦。 Using a global static doesn't sound much better. 使用全局静态听起来并不好。
It's actually simple. 实际上很简单。 If A
needs B
, it should accept B
as constructor argument: 如果A
需要B
,则应接受B
作为构造函数参数:
public class A
{
private readonly D1 d1;
private readonly D2 d2;
private readonly B b;
public A(D1 d1, D2 d2, B b) {
this.d1 = d1;
this.d2 = d2;
this.b = b;
}
}
public class B
{
private readonly D3 d3;
private readonly D4 d4;
private readonly C c;
public B(D3 d3, D4 d4, C c) {
this.d3 = d3;
this.d4 = d4;
this.c = c;
}
}
This way you build up object graphs recursively and you can get very deep object graphs, which is completely fine. 这样,您就可以递归地建立对象图,并且可以获得非常深的对象图,这完全可以。 This way you only need the container in the startup path of your application (aka the Composition Root). 这样,您只需在应用程序的启动路径(也称为“合成根目录”)中使用容器。
Whether or not A
needs B
'later on', or just sometimes, or hardly ever is irrelevant. A
是否需要“以后”使用B
,或者只是有时候,或者几乎不需要。 Building object graphs should be fast and whether or not B
is created needlessly should therefore not be an issue. 建立对象图应该很快,因此是否不必要创建B
不会成为问题。
Ideally you should never inject container to your classes just to resolve the the dependencies. 理想情况下,永远不要仅将容器注入类中以解决依赖关系。 Rather you register instances in in separate place probably your startup class where in runtime application should be able to resolve dependencies automatically from the registered instances with container. 而是将实例注册在单独的位置,可能是您的启动类,在运行时应用程序中,启动类应该能够从容器中的已注册实例自动解析依赖项。
look at following example how an IOC container typically register its instances 看下面的示例IOC容器通常如何注册其实例
Register 寄存器
SimpleIoc.Default.Register< IDataService, DataService >(); SimpleIoc.Default.Register <IDataService,DataService>(); SimpleIoc.Default.Register< MainViewModel >(); SimpleIoc.Default.Register <MainViewModel>();
SimpleIoc.Default.Register< SecondViewModel >(); SimpleIoc.Default.Register <SecondViewModel>();
Resolve 解决
SimpleIoc.Default.GetInstance< MainViewModel >(); SimpleIoc.Default.GetInstance <MainViewModel>();
At some point later on,
A
needs to create an instance of 'B', injecting its two dependencies into the constructor. 稍后,A
需要创建一个'B'实例,并将其两个依赖项注入到构造函数中。
In this case, A
must take a dependency on a BFactory
that can create the B
's for it. 在这种情况下, A
必须依赖可以为其创建B
的BFactory
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.