3

我處於需要修改第三方開源應用程序(NopCommerce)中的靜態存儲庫返回的內容的情況。問題是他們使用靜態存儲庫,所以我不能只繼承一個接口和DI我自己的存儲庫。我試圖在不修改NopCommerce代碼庫的情況下做到這一點......任何新鮮的想法?靜態存儲庫...不能使用DI,該怎麼辦?

編輯:我想NopCommerce使用我的回購,而不是讓我的代碼使用他們的。

+0

使用包裝類(es)封裝? – Tahbaza 2010-08-21 20:15:42

+0

然後,我不需要修改NopCommerce代碼來使用包裝類呢? – 2010-08-21 20:17:24

+0

@ jbarker7:不,你不會的。安娜李爾和哥布林(使用不同的術語)都建議你創建你自己的包裝類庫,你不能改變這些靜態包裝;你應該選擇其中兩個答案中的一個作爲正確答案。 – Tahbaza 2010-08-21 20:25:28

回答

3

我們目前正處於一個非常非常緊迫的期限,而且這個問題還沒有確定。所以我想首先從一個窮人的靜態界面/窮人的DI開始(因此我不必修改整個解決方案)。然後,在稍後的時間,當我們不那麼趕時間,在改變使用接口和依賴注入,並提交補丁NopCommerce:

// Poor-man's static interface (DI). 
public static class OriginalBuiltInStaticClass { 
    private static IMyNewClass _myNewClass; 

    public static void Inject(IMyNewClass myNewClass) { 
     _myNewClass = myNewClass; 
     A = _myNewClass.A; 
     B = _myNewClass.B; 
     C = _myNewClass.C; 
    } 

    public static Action A = CopySimpleRenameBuiltInStaticClass.A; 
    public static Func<int, string> B = CopySimpleRenameBuiltInStaticClass.B; 
    public static Action C = CopySimpleRenameBuiltInStaticClass.C; 
} 

// Original vendor class which was copied and renamed. 
public static class CopySimpleRenameBuiltInStaticClass { 
    public static void A() { 
     Console.WriteLine("OriginalBuiltInStaticClass.A()"); 
    } 

    public static string B(int id) { 
     Console.WriteLine("OriginalBuiltInStaticClass.B()"); 
     return id.ToString(); 
    } 

    public static void C() { 
     Console.WriteLine("OriginalBuiltInStaticClass.C()"); 
    } 
} 

// Creating an interface to merge into trunk of NopCommerce (convert static repositories) 
public interface IMyNewClass { 
    void A(); 
    string B(int id); 
    void C(); 
} 

// Implementation of interface. 
public class MyNewClass : IMyNewClass { 
    public void A() { 
     Console.WriteLine("MyNewClass.A()"); 
    } 

    public string B(int id) { 
     Console.WriteLine("MyNewClass.B()"); 
     return id.ToString(); 
    } 

    public void C() { 
     CopySimpleRenameBuiltInStaticClass.C(); 
    } 

} 

有什麼想法?

+0

這工作完美...我創建了一個T4模板,並自動生成接口,包裝器和實現類。現在,我剛剛放置: NopRepo.Inject(new MyExtClass.MyNopRepo()); 進入Application_Start和Viola中的Global.asax ...靜態類的DI。 – 2010-08-23 17:33:13

+0

對於那些對T4模板感興趣並更新此代碼的人:http://joshbarker.net/?p=33 – 2010-08-27 14:19:23

3

你可以通過創建你自己的接口和委託給NopCommerce的類實現來抽象出他們的東西。然後讓你的代碼使用界面,而不是直接訪問NopCommerce的類。在結果返回到您的應用程序之前,您可以修改類中NopCommerce的輸出。

作爲一個額外的好處,你也可以模擬接口做一些測試,不需要完整的知識庫實現。

事情是這樣的,在代碼:

public interface IRepository 
{ 
    MyItem GetItem(int id); 
} 

public class MyNopCommerceWrapper : IRepository 
{ 
    public MyItem GetItem(int id) 
    { 
     // I have no idea what NopCommerce API looks like, so I made this up. 
     var myItem = NopCommerce.GetItem(id); 

     ModifyMyItem(myItem); 

     return myItem; 
    } 
} 
+0

我想我正試圖圍繞你在這裏說的話把我的大腦包起來。基本上我們需要修改NopCommerce的工作方式以及返回到NopCommerce的內容。沒有其他應用程序。我只需要修改存儲庫,就好像我可以自己創建存儲庫一樣,或者如果它被標記爲虛擬的,我可以覆蓋它。 – 2010-08-21 20:22:08

+0

看起來像它的工作,但我仍然要修改NopCommerce使用這種包裝,而不是使用靜態庫的,對不對? – 2010-08-21 20:23:23

+0

不可以。您的應用程序不會了解NopCommerce庫的任何信息。它將被你的包裝類包裝,你的應用程序將只調用包裝的方法。只有包裝將依賴於NopCommerce。您的應用程序將能夠通過注入包裝來使用DI。沒有理由修改NopCommerce代碼庫 - 它不需要了解封裝。 – 2010-08-21 20:35:49