我處於需要修改第三方開源應用程序(NopCommerce)中的靜態存儲庫返回的內容的情況。問題是他們使用靜態存儲庫,所以我不能只繼承一個接口和DI我自己的存儲庫。我試圖在不修改NopCommerce代碼庫的情況下做到這一點......任何新鮮的想法?靜態存儲庫...不能使用DI,該怎麼辦?
編輯:我想NopCommerce使用我的回購,而不是讓我的代碼使用他們的。
我處於需要修改第三方開源應用程序(NopCommerce)中的靜態存儲庫返回的內容的情況。問題是他們使用靜態存儲庫,所以我不能只繼承一個接口和DI我自己的存儲庫。我試圖在不修改NopCommerce代碼庫的情況下做到這一點......任何新鮮的想法?靜態存儲庫...不能使用DI,該怎麼辦?
編輯:我想NopCommerce使用我的回購,而不是讓我的代碼使用他們的。
我們目前正處於一個非常非常緊迫的期限,而且這個問題還沒有確定。所以我想首先從一個窮人的靜態界面/窮人的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();
}
}
有什麼想法?
這工作完美...我創建了一個T4模板,並自動生成接口,包裝器和實現類。現在,我剛剛放置: NopRepo.Inject(new MyExtClass.MyNopRepo()); 進入Application_Start和Viola中的Global.asax ...靜態類的DI。 – 2010-08-23 17:33:13
對於那些對T4模板感興趣並更新此代碼的人:http://joshbarker.net/?p=33 – 2010-08-27 14:19:23
你可以通過創建你自己的接口和委託給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;
}
}
我想我正試圖圍繞你在這裏說的話把我的大腦包起來。基本上我們需要修改NopCommerce的工作方式以及返回到NopCommerce的內容。沒有其他應用程序。我只需要修改存儲庫,就好像我可以自己創建存儲庫一樣,或者如果它被標記爲虛擬的,我可以覆蓋它。 – 2010-08-21 20:22:08
看起來像它的工作,但我仍然要修改NopCommerce使用這種包裝,而不是使用靜態庫的,對不對? – 2010-08-21 20:23:23
不可以。您的應用程序不會了解NopCommerce庫的任何信息。它將被你的包裝類包裝,你的應用程序將只調用包裝的方法。只有包裝將依賴於NopCommerce。您的應用程序將能夠通過注入包裝來使用DI。沒有理由修改NopCommerce代碼庫 - 它不需要了解封裝。 – 2010-08-21 20:35:49
聽起來像是Facade工作。
使用包裝類(es)封裝? – Tahbaza 2010-08-21 20:15:42
然後,我不需要修改NopCommerce代碼來使用包裝類呢? – 2010-08-21 20:17:24
@ jbarker7:不,你不會的。安娜李爾和哥布林(使用不同的術語)都建議你創建你自己的包裝類庫,你不能改變這些靜態包裝;你應該選擇其中兩個答案中的一個作爲正確答案。 – Tahbaza 2010-08-21 20:25:28