0

我查閱了這些概念,並且想看看我是否正確理解了它們。主要是我試圖區分這三個概念。從這裏的谷歌搜索和其他結果中,我看到很多人提供的細節,但其中很多細節對我來說不是完全清楚,矛盾或交換了概念(IoC/DI)。我試圖用更簡單的方式來定義它們,這對我來說更容易消化,並且我想看看它是否足夠準確。控制反轉,依賴反轉和服務定位器差異說明

控制

客戶端類不直接實例化其依賴字段的實現類,因爲它依賴於某些其他外部類/源供給他們的反演。在大多數情況下,這些字段是具有一個或多個將作爲實現提供的子類的父類或接口。

依賴注入

客戶端類接收實現類及其相關領域,無論是通過構造函數,二傳手,或以其他方式,實施這一項目 是一個全新的對象實例。供應類可能會使用另一種模式,例如工廠,以確定傳遞給客戶端的實現(或者甚至可能直接實例化新實例並將其傳遞到客戶端的構造函數中)。

服務定位器

客戶端類是調用服務定位器提供其相關的領域之一。返回的實現是一個對象實例,可以與依賴於相同依賴關係的任何其他客戶端類共享。

我在一個非常簡單的例子試圖:

DI:

public interface IX { 

} 

public class X : IX { 

} 

public class A { 
    IX depField; 

    public A(IX depField) { 
     this.depField = depField; 
    } 
} 

public void main() { 
    A myClass = new A(new X()); 
} 

SL:

public interface IX { 

} 

public class X : IX { 

} 

public class A { 
    IX depField = serviceLocatorObj.GetService<IX>(); 
    //where IX is mapped to X in the service locator class 
} 

public void main() { 
    A myClass = new A(); 
} 

的IoC是在接收側的概念,其中,如DI和SL兩種處理供應方概念的可能方式。

謝謝。如果我錯誤地使用了任何條款,我也很抱歉。

編輯:感謝您的迴應!

+0

DI是執行IoC的一種方式。 IoC是「什麼」,DI是「如何」。 – 2013-05-10 16:25:14

回答

2

是的,你是對的。

SL通常在框架內部使用,以便能夠找到所有服務。從開發人員的角度來看,他們只是在框架隱藏服務位置時使用依賴注入。一個典型的例子是ASP.NET MVC,您可以在控制器中使用DI。 ASP.NET通過DependencyResolver類在內部使用服務位置來允許您使用DI。

對於業務應用程序,由於SL隱藏了依賴關係,所以DI優先於SL,這反過來又使維護應用程序變得更加困難。

1

服務位置也使得單元測試更加困難,因爲它們通常是靜態類,它們可以嘲笑它們。

考慮這些構造函數注入和服務位置的例子。

服務地點:

public class Foo 
    { 
     public void DoSomething() 
     { 
      var provider = ServiceLocator.GetInstance<IProvider>(); 

      provider.DoIt(); 
     } 
    } 

構造方法注入:

public class Foo 
    { 
     private readonly IProvider _provider; 

     public Foo(IProvider provider) 
     { 
      _provider = provider; 
     } 

     public void DoSomething() 
     { 
      _provider.DoIt(); 
     } 
    } 

它是簡單的通過一個模擬/假IProvider在構造函數中,而在服務定位器例如本成倍越難你首先需要抽象ServiceLocator類。

[Test] 
    public void DoSomething_ShouldCallDoIt() 
    { 
     var mockProvider = new Mock<IProvider>(); 

     var foo = new Foo(mockProvider); 

     foo.DoSomething(); 

     mockProvider.Verify(x => x.DoIt()); 
    }