通常,我会在 C# 中使用依赖注入(inject)容器(unity),如下例所示:
class SomeClass
{
private readonly ILogger _logger;
public SomeClass()
{
_logger = DependencyContainer.Resolve<ILogger>();
}
public void DoSomething()
{
var someOtherClass = DependencyContainer.Resolve<...>();
someOtherClass().whatElseEver();
}
}
昨天,我读了一些关于使用 di 容器进行正确依赖注入(inject)的文章。在此之后,我知道我的例子完全不好。这不是依赖注入(inject),这只是类似服务定位器的东西。
好的,这个问题怎么解决呢?我认为通过构造函数注入(inject)可以轻松解决这个问题:
class SomeClass
{
private readonly ILogger _logger;
private readonly ISomeOtherClass _someOtherClass;
public SomeClass(ILogger logger, ISomeOtherClass someOtherClass)
{
_logger = logger;
_someOtherClass = someOtherClass;
}
public void DoSomething()
{
_someOtherClass().whatElseEver();
}
}
现在我已经正确实现了依赖注入(inject)原理。 但如何连接所有这些依赖关系呢?我有一个调用者类,它解决了“SomeClass”类所需的所有礼仪:
class SomeClassCaller
{
public void DoSomething()
{
var logger = DependencyContainer.Resolve<ILogger>();
var someOtherClass = DependencyContainer.Resolve<...>();
var someClass = new SomeClass(logger, someOtherClass);
someClass.DoSomething();
}
}
但是这个示例仍然使用依赖容器作为服务定位器,这很糟糕。在几乎每一篇关于此的文章中,我读过,依赖项容器只能在应用程序根/入口点使用,这是正确的吗?
这意味着,任何类都不应具有通过“服务定位器”动态解决某些依赖关系的能力,例如记录器。我必须通过构造函数将 ILogger 注入(inject)到几乎每个类中,以避免这个问题,对吗?如果我将 ILogger 通过大约 10 个类放入每个构造函数中,这种方式感觉非常糟糕,不是吗?
那么,如果我有一个复杂的依赖关系图,我必须仅使用依赖关系容器?
如果您仅在应用程序的根目录使用依赖项容器,有人可以给我一个示例吗?
最佳答案
如果SomeClassCaller
需要SomeClass
,则注入(inject)它:
public class SomeClassCaller
{
private readonly SomeClass someClass;
public SomeClassCaller(SomeClass someClass)
{
this.someClass = someClass;
}
public void DoSomething()
{
this.someClass.DoSomething();
}
}
这是 Concrete Dependency 的示例。不过,通常情况下,您可以让 SomeClass
实现一个接口(interface),然后将该接口(interface)注入(inject)到 SomeClassCaller
中,而不是具体的类中。
在 Composition Root您可以连接您的对象图:
var scc = new SomeClassCaller(
new SomeClass(
new MyLogger(),
new SomeOtherClass()));
您不需要 DI 容器来执行此操作,但如果您愿意,可以使用一个容器。
关于c# - 仅在应用程序启动时使用 DI 容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35650884/