正式开始本文:在 .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