2015-07-21 126 views
3

我開始與依賴注入,並有困難的時候obestcting一些第三方庫類。例如我在我的項目中有EPPlus庫,它有一個沒有實現接口的ExcelRange類。由於我正在使用這個庫,我發現我的代碼顯式依賴,無法正確地單元測試代碼的某些部分。什麼是最好的方式來包裝第三方類c#

所以我的問題是什麼是與第三方庫類使用依賴注入的好方法。

+0

有一些書討論解決像GoF(又名設計模式)這樣的問題的方法和「有效地使用遺留代碼」的方法。除了廣泛涉及您的問題之外,這兩本書都是非常有用的優秀閱讀材料。 –

回答

5

我對這種情況的解決方法是創建另一個類和接口作爲包裝到您的第三方庫。在包裝中,創建與您在第三方庫中使用的名稱相同的函數。只創建那些對代碼有價值的函數,如果你需要其他函數將它們添加到你的包裝中,則一點一點地創建這些函數。現在,出於測試目的,您可以模擬/存根您的包裝界面,而無需使用第三方庫。使用你的包裝器注入其他需要此服務的類。

你可以用簡單的代碼開始並擴大它作爲你的知識增長:

public interface IWrapperService 
{ 
    Method(Dto model); 

    Dto MethodProcess(Dto model); 
} 

public class WrapperService : IWrapperService 
{ 
    private readonly ThirdPartyLib _thirdPartyLib; 

    public WrapperService(ThirdPartyLib thirdPartyLib) 
    { 
     _thirdPartyLib = thirdPartyLib; 
    } 

    // Create your model - Dto 
    // Dto will help you in your logic process 
    // 
    public void Method(Dto model) 
    { 
     //extract some properties in you model that only needed in your third party library 
     _thirdPartyLib.Method(parameter needed); 
    } 

    public Dto MethodProcess(Dto model) 
    { 
     //extract some properties in you model that only needed in your third party library 
     ThirdPartyReturn value = _thirdPartyLib.MethodProcess(parameter needed); 

     // Do the mapping 
     var model = new Dto 
     { 
      property1 = value.property1 // Do the necessary convertion if needed. 
      . 
      . 
     } 

     return model; 
    } 
    . 
    . 
    . 
} 

public interface IOtherClass 
{ 
    ... 
} 

public class OtherClass : IOtherClass 
{ 
    private readonly IWrapperService _wrapperService; 

    public void OtherClass(IWrapperService wrapperService) 
    { 
     _wrapperService= wrapperService; 
    } 
    . 
    . 
} 

依賴注入,您可以使用Microsoft unity。它會爲你的依賴做出驚人的工作。您可以使用它像這樣:

var unity = new UnityContainer(); 

// This is how you will inject your ThirdPartyLib 
// You can also do it this way - unity.RegisterType<ThirdPartyLib>() but of course we need to limit the usage of your ThirdPartyLib in 
// our wrapper. We will not allowing directly access to Third Party Lib rather than wrapperService. 

unity.RegisterType<IWrapperService, WrapperService>(new InjectionConstructor(new ThirdPartyLib())); 
unity.RegisterType<IOtherClass, OtherClass>(); 

我@Alexei Levenkov同意,你需要閱讀有關四(GOF)的岡一些東西來改善這個樣品。以我的樣本爲出發點。

包裝一下你的第三方庫爲您提供了以下優點:

  • 它消除您的第三方庫的分散,直接使用。
  • 它在你的第三方lib中封裝了一些複雜性。
  • 通過包裝來跟蹤和維護第三方庫很容易。
  • 現在通過使用包裝來簡化單元測試。
  • 而依賴注入將幫助您解決跨領域問題。

一些缺點:

  • 繁瑣和介紹的方法的重複。
  • 介紹新模型的創建 - 它取決於,如果您的第三方lib只詢問像(int,string,boolean)這樣的參數不會爲模型打擾。
  • 首先應用設計模式可能很困難,但從長遠來看,它會給您帶來好處。
+0

謝謝你的迴應。這是一個相當大的圖書館。如果沒有別的辦法,我想我已經花時間去做了。你能舉個例子嗎? – Farukh

相關問題