正式開始本文:在 .Net 框架中,將程序集加載至應用程序域的方法有幾種。每種方法使用不同的類。
您可以使用下面的重載方法將程序集加載至應用程序域:
System.AppDomain 類包含幾種重載的 Load 方法。盡管這些方法可用於將任何程序集成功地加載至當前的或新的應用程序域,但它們主要還是用於 COM 交互操作。您也可以使用 CreateInstance 方法加載程序集。
System.Reflection.Assembly 類包含兩種靜態重載方法:Load 和 LoadFrom。這兩種方法因加載上下文而異。
簡單例題:講解了在一個.exe文件中調用另一個.exe文件的方法
using System;
namespace dy_loadAsse
{
class testclass
{
[STAThread]
static void Main(string[] args)
{
OutUse test=new OutUse();
test.Output();
Console.ReadLine();
}
}
class OutUse
{
public OutUse()
{
}
public void Output()
{
Console.WriteLine("test dy load assembly");
}
}
}
以上編譯成功。為dy_loadAsse.exe,執行顯示:
test dy load assembly
放在與下面生成的loadexe.exe於同一目錄下。
文件二:
using System;
using System.Reflection;
namespace Use_dy_Load_Assembly
{
class LoadExe
{
[STAThread]
static void Main(string[] args)
{
// Use the file name to load the assembly into the current application domain.
Assembly a = Assembly.LoadFrom("dy_loadAsse.exe");
Type [] types2 = a.GetTypes();
foreach (Type t in types2)
{
Console.WriteLine (t.FullName);
}
//Get the type to use.
//Type myType = a.GetType("OutUse"); 這樣寫老是出錯
Type myType = a.GetType("dy_loadAsse.OutUse");
Console.WriteLine (myType.FullName);
//Get the method to call.
MethodInfo mymethod = myType.GetMethod("Output");
// //Create an instance.
Object obj = Activator.CreateInstance(myType);
// //Execute the adnamemethod method.
mymethod.Invoke(obj,null);
//執行結果為test dy load assembly
//以下是調用dy_loadAsse.exe中的Main方法,出現錯誤
// Type myType = a.GetType("dy_loadAsse.testclass");
// Console.WriteLine (myType.FullName);
// //Get the method to call.
// MethodInfo mymethod = myType.GetMethod("Main");
// //// //Create an instance.
// Object obj = Activator.CreateInstance(myType);
// //// //Execute the adnamemethod method.
// mymethod.Invoke(obj,null);
Console.ReadLine();
}
}
}
實際上不管你是.exe或dll 組成的程序集 都可以被加載
自定義綁定
除了由編譯器隱式地用來進行晚期綁定之外(指virtual方法,接口等相關實現的綁定),反射還可以在代碼中顯式地用來完成晚期綁定。 公共語言運行庫支持多種編程語言,但這些語言的綁定規則各不相同。在早期綁定的情況下,代碼生成器可以完全控制此綁定。但是,當通過反射進行晚期綁定時,必須用自定義綁定來控制綁定。Binder 類提供了對成員選擇和調用的自定義控制。
利用自定義綁定,您可以在運行時加載程序集,獲取有關該程序集中類型的信息,然後對該類型調用方法或訪問該類型的字段或屬性。如果您在編譯時(例如當對象類型依賴於用戶輸入時)不知道對象的類型,就可以使用這種方法。
using System;
namespace dy_loaddll
{
public class HelloWorld
{
// Constant Hello World string.
private const String m_helloWorld = "Hello World";
// Default public constructor.
public HelloWorld()
{
}
// Print "Hello World" plus the passed text.
public void PrintHello(String txt)
{
// Output to the Console.
Console.WriteLine(m_helloWorld + " " + txt);
}
}
}
編輯生成dy_loaddll.dll,與 LoadExe.exe在同一的目錄下面。
using System;
using System.Reflection;
namespace Use_dy_Load_Assembly
{
class LoadExe
{
[STAThread]
static void Main(string[] args)
{
// Use the file name to load the assembly into the current application domain.
Assembly a = Assembly.LoadFrom("dy_loaddll.dll");
Type [] types2 = a.GetTypes();
foreach (Type t in types2)
{
Console.WriteLine (t.FullName);
}
//Get the type to use.
// Type myType = a.GetType(""); 這樣寫老是出錯因為上面的dll加了命名空間
Type myType = a.GetType("dy_loaddll.HelloWorld");
// Type myType = a.GetType("HelloWorld");
Console.WriteLine (myType.FullName);
// //Get the method to call.
MethodInfo printMethod = myType.GetMethod("PrintHello");
// Create an instance of the HelloWorld class.
Object obj = Activator.CreateInstance(myType);
// Create the args array.
Object[] test = new Object[1];
// Set the arguments.
test[0] = "From CSharp Late Bound";
// Invoke the PrintHello method.
printMethod.Invoke(obj, test);
Console.ReadLine();
}
}
}
當然我們不禁要問題,如果方法重載,如果是屬性。又該怎麼辦??
/查相關的msdn,
ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/Html/cpcondynamicallyloadingusingtypes.htm#cpcondynamicallyloadingusingtypes
ms-help://MS.VSCC/MS.MSDNVS.2052/cpref/Html/frlrfSystemTypeClassInvokeMemberTopic.htm