簡體   English   中英

使用IoC進行即興創作-Unity

[英]Improvising using IoC - Unity

我正在嘗試在應用程序中利用依賴注入技術,但是如果此上下文需要DI則感到困惑。

考慮一個接口:

public class ICardsHub {
    public T GetPlayersList<T>();
}

及其實現:

public class GenericHub : ICardsHub {

    LANPlayers LANPlayers;
    WaNPlayers WANPlayers;
    bool AlgorithmsUseTildainLambdas=false;

    public GenericHub(LANPlayers _LANPlayers, WaNPlayers _WANPlayers, 
                           bool algorithmsUseTildainLambdas=false) {
        LANPlayers = _LANPlayers;
        WANPlayers = _WANPlayers;
        AlgorithmsUseTildainLambdas = algorithmsUseTildainLambdas;
    }

    public T GetPlayersList<T>() {
        ....
    }

}

並且驅動程序類應該執行以下操作:

ICardsHub _ifCards = new GenericHub(_LANPlayers, _WANPlayers);
listOfPlayers = _ifCards.GetPlayersList<List<string>>();

現在,我們還有ICardsHub兩個實現; RedHubBlackHub在驅動程序類的后面實例化。

問題

  1. Unity IoC / DI如何使這種情況受益?
  2. 如果從接口中剝離方法參數並將其注入重載構造函數即可解決問題,那么使用DI容器的合適方案是什么?

DI使代碼易於維護和易於轉換到新的實現。 我同意重載的構造函數將達到目的,但是如果您有很多依賴關系,我們仍然必須手動確保對代碼進行更改以有效地到達每個位置並手動更改它,有時您可能會錯過其中的一些。 具有中心位置將有助於輕松維護。 這就是不建議在較小的項目中建議使用DI的原因,而在較大的項目中建議不要使用DI。 我認為DI不是解決TDD的目的,而是更好的可維護性和易於切換到類的新實現的目的。 例如,今天您使用SQL SERVER作為數據庫,明天使用NOSQL。 類名的一個地方更改將確保所有與DB交互的代碼在所有地方都能正常工作。 TDD是示例之一

DI的主要動機是可測試性,恕我直言。 因此,如果您不看測試范式,可能會有些困惑。

在您描述的示例中,我看到ICardsHub為GenericHub,RedHub和BlackHub的實現定義了一個合同。

現在,這些實現中的每一個都將具有使其不同的邏輯,因此需要存在不同的類。

為了測試這些類(它們的職責是唯一的),在這些類可以執行其工作之前,需要執行一些步驟,並且可能需要在這些步驟之后發布一些內容。

此類的測試范圍是確保給定“前置”步驟無錯誤,此類執行的操作將具有無錯誤輸出,以供“后置”步驟使用。

考慮到這一點,依賴注入使我們能夠

  1. 輕松地假設前提條件(即通過假設設置注入模擬對象)
  2. 執行一個動作(該類的責任)
  3. 驗證輸出。

順便說一句,您的實現應該注入接口而不是具體類型。 就像是 -

ILANPlayers LANPlayers;
IWaNPlayers WANPlayers;
bool AlgorithmsUseTildainLambdas=false;

public GenericHub(ILANPlayers _LANPlayers, IWaNPlayers _WANPlayers, 
                       bool algorithmsUseTildainLambdas=false) {
    LANPlayers = _LANPlayers;
    WANPlayers = _WANPlayers;
    AlgorithmsUseTildainLambdas = algorithmsUseTildainLambdas;
} 

這樣,在測試中您可以模擬ILanPlayersIWanPlayers ,它們實質上是這些類型的模擬實現。

通常,您僅使用DI來幫助您執行單元測試。 您應該針對接口進行編碼,因此,使用DI可以輕松模擬組件。

在您的方案中,您將使用ICardHub接口的實現來使用一些客戶端類,現在的問題是,這些實現中的任何一個都將執行數據庫操作或任何其他外部用法,如果沒有的話,您最好不使用DI。

如果仍要使用DI,請改用AutoFac,這很容易使用IMO。

如果您認為有一段代碼可以創建一個“庫”,那么這就是DI的不錯選擇。 您必須將這些組件視為提供者,而DI通常並不新鮮。 DI只是通過創建所需的提供程序的實例來消除應用程序的責任,這是DI容器在做的,並且您的應用程序僅與接口一起使用。

這是一個例子:

  • 沒有DI

     IDatabase database = new SqlServer(); 
  • 帶DI

     IDatabase database = DIContainer.Get<IDatabase>(); 

如您所見,即使您的應用程序將使用SqlServer數據庫,它對此一無所知。 是的,您必須在DI容器中注冊該類型,但是只能執行一次,因此,如果您以后決定更改為其他實現,則非常簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM