通常,我会在c#中使用依赖注入容器(unity),如下例所示:
/Users/sunnyjain/Desktop/vernemq/_build/dev1/rel/vernemq/bin
昨天,我已经阅读了一些关于使用di容器进行正确依赖注入的文章。在此之后,我知道我的榜样非常糟糕。这不是依赖注入,这就像服务定位器。
好的,怎么解决这个问题?我认为使用构造函数注入可以轻松解决这个问题:
class SomeClass
{
private readonly ILogger _logger;
public SomeClass()
{
_logger = DependencyContainer.Resolve<ILogger>();
}
public void DoSomething()
{
var someOtherClass = DependencyContainer.Resolve<...>();
someOtherClass().whatElseEver();
}
}
现在我已经正确实现了依赖注入原则。 但是如何连接所有这些依赖项呢?我有一个调用者类,它解决了“SomeClass”类所需的所有重要性:
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();
}
}
但是这个例子仍然使用依赖容器作为服务定位器,这很糟糕。在几乎所有关于此的文章中,我都读过,只应该在应用程序的根/入口点使用依赖容器这是正确的吗?
这意味着,没有类应该能够像运行记录器那样动态解决与“服务定位器”的某些依赖关系。我要通过构造函数将ILogger注入到几乎每个类中,以避免这个问题,对吗?这种方式感觉非常糟糕,如果我把ILogger通过10个类进入每个构造函数,不是吗?
所以,如果我有一个复杂的依赖图,我只能使用依赖项容器吗?
如果您使用依赖项容器,只有在应用程序的根目录下,有人能给我一个示例吗?
答案 0 :(得分:3)
如果SomeClassCaller
需要SomeClass
,请将其注入:
public class SomeClassCaller
{
private readonly SomeClass someClass;
public SomeClassCaller(SomeClass someClass)
{
this.someClass = someClass;
}
public void DoSomething()
{
this.someClass.DoSomething();
}
}
这是Concrete Dependency的示例。通常,您可以让SomeClass
实现一个接口,然后将该接口注入SomeClassCaller
,而不是具体的类。
在Composition Root中,您可以连接对象图:
var scc = new SomeClassCaller(
new SomeClass(
new MyLogger(),
new SomeOtherClass()));
您不需要DI容器来执行此操作,但如果您愿意,可以使用一个。