利用反射的原理创造类型的实例在动态创建类的实例时候非常有用处,比如在插件体系结构的软件中,声明一个插件接口,然后根据程序集Assembly生成相应的实例。
下面以简单的程序为例,SharedDemo2中含有一个简单类Class1,这个程序集的名称是SharedDemo2.dll, 调用该程序集的名称叫ConsoleApplication6.exe
类Class1的代码
using System;
using System.Collections.Generic;
using System.Text;
namespace SharedDemo2
{
public class Class1
{
private string name = string.Empty;
public Class1(string name)
{
this.name = name;
}
public string Name
{
get { return this.name; }
}
}
}
ConsoleApplication6 的代码
namespace ConsoleApplication6
{
public class Class2
{
private Assembly loaderAssembly;
private const string loaderFULLNAME = "SharedDemo2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f4af5318ff02e31a";
private const string loaderNAMESPACE = "SharedDemo2.Class1";
public Class1 GetSimplyShared()
{
Assembly simplyShareAssembly = Assembly.Load(loaderFULLNAME);
Class1 simplyShared = (Class1)simplyShareAssembly.CreateInstance(loaderNAMESPACE, false, BindingFlags.Instance|BindingFlags.Public, null, new object[] { "here is the name" },null,null);
return simplyShared;
}
}
}
入口函数
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using SharedDemo2;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
Class2 class2 = new Class2();
Class1 shared = class2.GetSimplyShared();
Console.WriteLine(shared.Name);
Console.Read();
}
}
}
1. 为SharedDemo2.dll使用强名称签名
a) 使用SDK 中SN工具生成一个key文件(Sn –k gacdemo.snk)
b) 在SharedDemo2工程中指定这个Assembly的签名(gacdemo.snk)
c) 使用SN工具查看程序集的公钥publicToken (Sn –Tp SharedDemo.dll)
2. 在ConsoleApplicatoin6 使用反射Assembly.CreateInstance
a) 定义SharedDemo2的Assembly的fullname("SharedDemo2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f4af5318ff02e31a")
b) 在ConsoleApplication 添加引用SharedDemo2.dll,并实现动态加载Assembly和CreateInstance,
Assembly simplyShareAssembly = Assembly.Load(loaderFULLNAME);
Class1 simplyShared = (Class1)simplyShareAssembly.CreateInstance(loaderNAMESPACE, false, BindingFlags.Instance|BindingFlags.Public, null, new object[] { "here is the name" },null,null);
return simplyShared;
其中特别要注意的是bindingFlags,必须保留Instance和public flags,否则将会出现异常-不能找到Class1的构造函数。