一:應用程式定義域 介紹:
"域",就是範圍,環境,邊界的意思,那麼什麼是應用程式定義域,官方給出的是這樣的解釋:作業系統和運行庫環境通常會
在應用程式間提供某種形式的隔離.
應用程式定義域為安全性、可靠性、版本控制以及卸載程式集提供了隔離邊界。應用程式定義域通常由運行庫宿主建立,
運行庫宿主負責在運行應用程式之前引導公用語言運行庫。
應用程式定義域本質上就就是一種隔離,目的也就是使應用程式中啟動並執行代碼不能直接存取其他應用程式中的代碼或資
源如果你需要訪問其他應用程式中的對象時你就可以複製這些對象,或通過代理訪問這些對象.
二:應用程式定義域和程式集
應用程式定義域和程式集之間的關係。在可以執行程式集中所包含的代碼之前,必須將程式集載入到應用程式定義域中。
運行普通的應用程式會導致將幾個程式集載入到一個應用程式定義域中。
程式集的載入方式決定其即時 (JIT) 編譯代碼是否可以在進程中由多個應用程式定義域共用,以及該程式集是否可以
從進程中卸載:
1:如果程式集是以非特定於域的形式進行載入,則共用相同安全授權集的所有應用程式定義域都可以共用相同的 JIT 編
譯代碼,從而減少應用程式所需的記憶體。但是,程式集則永遠不能從進程中卸載。
2:如果程式集不是以非特定於域的形式進行載入,則它必須在載入的每個應用程式定義域中都是 JIT 編譯的。但是,通過卸載程式集載入的所有應用程式定義域,可以從進程中卸載程式集。
三:AppDomain class 的使用
在.NET Framework 提供了AppDomain類來實現以建立和卸載域、建立域中各類型的執行個體.那麼該類中有哪些方法呢,
下面我們進行簡單的介紹:
1:CreateDomain :用於創新的應用程式定義域,
2:ExecuteAssembly or ExecuteAssemblyByName方法:執行應用程式定義域中的程式集。這是一個執行個體方法,因此它
可用來執行另一個應用程式定義域(您擁有對該域的引用)中的代碼:
3:CreateInstanceAndUnwrap:在應用程式定義域中建立指定類型的執行個體,並返回一個代理。使用此方法以避免將包含創
建的類型的程式集載入到調用程式集.
4:Unload:執行域的正常關閉.只有應用程式定義域中正在啟動並執行所有線程都已停止或域中不再有啟動並執行線程之後,才卸載
該應用程式定義域。
四:編程例子:
以下這個例子顯示了如何他建立應用程式定義域和關閉應用程式定義域:
using System;
using System.Reflection;
using System.Threading;
class Example
{
public static void Main()
{
string callingDomainName = Thread.GetDomain().FriendlyName;
string exeAssembly = Assembly.GetEntryAssembly().FullName;
// 設定一個新的應用程式定義域
AppDomainSetup a= new AppDomainSetup();
a.ApplicationBase =
System.Environment.CurrentDirectory;
a.DisallowBindingRedirects = false;
a.DisallowCodeDownload = true;
a.ConfigurationFile =
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// 建立新的應用程式定義域
AppDomain b= AppDomain.CreateDomain("b", null, ads);
MarshalByRefType mbrt =
(MarshalByRefType) b.CreateInstanceAndUnwrap(
exeAssembly,
typeof(MarshalByRefType).FullName
);
mbrt.SomeMethod(callingDomainName);
// 關閉應用程式定義域
AppDomain.Unload(ad2);
try
{
// Call the method again. Note that this time it fails
// because the second AppDomain was unloaded.
mbrt.SomeMethod(callingDomainName);
Console.WriteLine("Sucessful call.");
}
catch(AppDomainUnloadedException)
{
Console.WriteLine("Failed call; this is expected.");
}
}
}
public class MarshalByRefType : MarshalByRefObject
{
//通過代理調用方法
public void SomeMethod(string callingDomainName)
{
AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation;
Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}",
a.ApplicationName,
a.ApplicationBase,
a.ConfigurationFile
);
Console.WriteLine("Calling from '{0}' to '{1}'.", callingDomainName,
Thread.GetDomain().FriendlName );
}
}