某項(xiàng)目要調(diào)用現(xiàn)有的100多個(gè)DLL 三 先解決為一個(gè)類型做一個(gè)跨域的問題
將同類的操作Wrap在同一個(gè)類型中,如以下代碼:
/// <summary>
/// really business operation.
/// </summary>
[Serializable]
public class ServiceWrapper1 : MarshalByRefObject
{
protected ServiceWrapper1()
{
}
public virtual List<OpaOutput> GetUserDto(OpaInput input)
{
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + " Test2"); //show current domain
OPATest test = new OPATest();
return test.GetUserDto(input);
}
}
}
這是一個(gè)簡(jiǎn)單的wrap 用于調(diào)用另外一個(gè)dll的OPATest 類 , 同時(shí)測(cè)試一下代碼是否運(yùn)行在獨(dú)立的域中
構(gòu)造函數(shù)變?yōu)镻rotected的主要原因是禁止直接通過構(gòu)造函數(shù)新建wrap實(shí)例,強(qiáng)迫通過DefaultInstance的方式調(diào)用代碼 (這樣才是應(yīng)用程序隔離的)
不變成Private的原因是之后還需要有繼承 如果把父類的構(gòu)造函數(shù)設(shè)置為private 那么子類也構(gòu)造不了
但是在當(dāng)前代碼中 你應(yīng)該把protected改為public 才可以正常的運(yùn)行,
為了解決跨域的問題 將wrap類繼承于 MarshalByRefObject ,
OpaInput和 OpaOutput分別是輸入輸出參數(shù) (定義在現(xiàn)有的dll中 為了方便開發(fā) 先暫時(shí)定義為可以序列化,真正的序列化實(shí)現(xiàn)的問題稍后解決)以下是他們的定義
namespace ClassLibrary2
{
public class OPATest
{
public List<OpaOutput> GetUserDto(OpaInput input)
{
return new List<OpaOutput> {
new OpaOutput() { Date=DateTime.Now },
new OpaOutput(){Date=DateTime.Now},
new OpaOutput(){Date=DateTime.Now},
};
}
}
[Serializable]
public class OpaOutput
{
public string Name { get; set; }
public string Content;
public int Type;
public DateTime Date { get; set; }
}
[Serializable]
public class OpaInput
{
public string UserCode { get; set; }
public string Content;
public int? Type;
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
}
為了方便的訪問跨域的dll 實(shí)現(xiàn)了以下類型
[Serializable]
public class BaseWrapper<T> : MarshalByRefObject
{
/// <summary>
/// define a application domain for every T
/// </summary>
private static AppDomain _CurrentDomian = null;
/// <summary>
/// static constructor
/// </summary>
static BaseWrapper()
{
string domainName = "Application Execution Domain " + typeof(T).FullName;
_CurrentDomian = AppDomain.CreateDomain(domainName, null, null);
}
/// <summary>
/// forbid call constructor directly.
/// </summary>
protected BaseWrapper()
{
}
/// <summary>
/// singleton instance.
/// </summary>
public static T DefaultInstance
{
get
{
return (T)_CurrentDomian.CreateInstanceAndUnwrap(typeof(T).Assembly.FullName, typeof(T).FullName);
}
}
}
那么跨域的調(diào)用就非常簡(jiǎn)單了,并且為一個(gè)類型T維護(hù)一個(gè)ApplicationDomain
調(diào)用代碼如下所示:
BaseWrapper<ServiceWrapper1>.DefaultInstance.GetUserDto(new ClassLibrary2.OpaInput() { Content = "123" });
非常的簡(jiǎn)單 和原來的調(diào)用代碼相比 增加的代碼量一點(diǎn)都不多,原來的調(diào)用代碼如下所示
ServiceWrapper1 s = new ServiceWrapper1();
s.GetUserDto(new ClassLibrary2.OpaInput() { Content = "123" });
最終運(yùn)行結(jié)果如下:
Application Execution Domain ClassLibrary1.ServiceWrapper1 Test2
說明 這個(gè)方法是在新的應(yīng)用程序域中執(zhí)行
PS:這里做了一個(gè)假設(shè) 即輸入輸出刪除可序列化, 實(shí)際上不是所有的人聲明代碼的時(shí)候都會(huì)加上可序列化標(biāo)簽的 稍后我們來解決這個(gè)問題
那么到目前為止 我們把所有調(diào)用外部dll的代碼集中到了一部分類里面,并且隔離在不同的應(yīng)用程序域來執(zhí)行了
posted on 2011-02-14 11:40 聽說讀寫 閱讀(530) 評(píng)論(0) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)