2016-02-26 27 views
1

通常情况下,我会使用C#中的依赖注入容器(单位)这样的例子:仅在应用程序启动时使用DI容器?

class SomeClass 
{ 
    private readonly ILogger _logger; 

    public SomeClass() 
    { 
     _logger = DependencyContainer.Resolve<ILogger>(); 
    } 

    public void DoSomething() 
    { 
     var someOtherClass = DependencyContainer.Resolve<...>(); 
     someOtherClass().whatElseEver(); 
    } 
} 

昨天,我已经知道了正确的依赖注入二容器的一些文章。在此之后,我知道我的例子完全不好。这不是依赖注入,这只是一个服务定位器。

好的,该如何解决?我想与构造注入就可以轻松解决这个问题:

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(); 
    } 
} 

现在我有正确执行的依赖注入的原则。 但如何连接所有这些依赖关系?我有一个呼叫者类解决类“SomeClass的”所需的全部decencies:

class SomeClassCaller 
{ 
    public void DoSomething() 
    { 
     var logger = DependencyContainer.Resolve<ILogger>(); 
     var someOtherClass = DependencyContainer.Resolve<...>(); 

     var someClass = new SomeClass(logger, someOtherClass); 
     someClass.DoSomething(); 
    } 
} 

但这个例子仍然使用依赖性容器作为服务定位器,这是不好的。几乎在每篇关于这个的文章中,我都读过,应该只使用依赖容器,在应用程序的根/入口点,这是正确的吗?

这意味着,没有类应该有能力解决一些依赖与“服务定位器”的动态,如记录器。我必须通过构造函数将ILogger注入几乎每个类,以避免此问题,对吗?这种方式感觉很糟糕,如果我把ILogger通过10个类加入到每个构造函数中,不是吗?

所以,我只使用一个依赖容器,如果我有一个复杂的依赖关系图?

有人可以给我一个例子,如果你使用一个依赖容器,它只是在应用程序的根目录?

+0

请参阅[this](http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-the-context-of-dependency-injection)答案。关于这个完全相同的问题,还有很多这样的问题。 – kayess

+0

你似乎对一般的东西有很好的处理。你必须立即做这件事的一件事就是在.NET中购买Mark Seemann的DI - 你不会后悔的;它将填补你的思维过程中的许多空白,以及一般的软件架构。现在,对于你的实际问题,我不确定你在问什么,但我有一个预感,这篇文章可能对你有用,以显示如何将基本参数与对消费类没有直接作用的基本参数分开:http ://docs.autofac.org/en/latest/advanced/delegate-factories.html –

回答

3

如果需要SomeClassCallerSomeClass,注入它:

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容器要做到这一点,但您可以使用一个,如果你喜欢。

+0

谢谢你,这可以帮助我很多。在我们公司,我们完全使用IoC容器完成了依赖项注入,我们使用IoC容器作为服务定位器。现在,我很清楚如何使用IoC容器,谢谢。 –

相关问题