//dll
namespace Dynamic_linking{ public partial class ShowErrorForm : Form { public ShowErrorForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { MessageBox.Show("It is children!"); } public int Add(int x, int y) { return x + y; } }}
//controller
namespace Mainform{ public class LDFS { // 记录要导入的程序集 static Assembly MyAssembly; /// <summary> /// 添加LoadDll方法 /// </summary> /// <param name="lpFileName"></param> /// <returns></returns> private byte[] LoadDll(string lpFileName) { Assembly NowAssembly = Assembly.GetEntryAssembly(); Stream fs = null; try {// 尝试读取资源中的 DLL 同一命名空间下 fs = NowAssembly.GetManifestResourceStream(NowAssembly.GetName().Name + "." + lpFileName); } finally {// 如果资源没有所需的 DLL ,就查看硬盘上有没有,有的话就读取 if (fs == null && !File.Exists(lpFileName)) throw (new Exception(" 找不到文件 :" + lpFileName)); else if (fs == null && File.Exists(lpFileName)) { FileStream Fs = new FileStream(lpFileName, FileMode.Open); fs = (Stream)Fs; } } byte[] buffer = new byte[(int)fs.Length]; fs.Read(buffer, 0, buffer.Length); fs.Close(); return buffer; // 以 byte[] 返回读到的 DLL } /// <summary> /// 添加UnLoadDll方法来卸载DLL /// </summary> public void UnLoadDll() {// 使 MyAssembly 指空 MyAssembly = null; } /// <summary> /// 添加Invoke方法来进行对DLL中方法的调用 /// </summary> /// <param name="lpFileName">dll名称</param> /// <param name="Namespace">命名空间</param> /// <param name="ClassName">类名</param> /// <param name="lpProcName">调用函数的名称</param> /// <param name="ObjArray_Parameter">参数</param> /// <returns></returns> public object Invoke(string lpFileName, string Namespace, string ClassName, string lpProcName, object[] ObjArray_Parameter) { try {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集 if (MyAssembly == null || MyAssembly.GetName().Name != Namespace) MyAssembly = Assembly.Load(LoadDll(lpFileName)); Type[] type = MyAssembly.GetTypes(); foreach (Type t in type) { if (t.Namespace == Namespace && t.Name == ClassName) { MethodInfo m = t.GetMethod(lpProcName); if (m != null) {// 调用并返回 object o = Activator.CreateInstance(t); return m.Invoke(o, ObjArray_Parameter); } else System.Windows.Forms.MessageBox.Show(" 装载出错 !"); } } } catch (System.NullReferenceException e) { System.Windows.Forms.MessageBox.Show(e.Message); } return (object)0; } public object Invoke(string lpFileName, string Namespace, string ClassName) { try {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集 if (MyAssembly == null || MyAssembly.GetName().Name != Namespace) MyAssembly = Assembly.Load(LoadDll(lpFileName)); Type type = MyAssembly.GetType(Namespace + "." + ClassName); if (type.Namespace == Namespace && type.Name == ClassName) { object classobj = Activator.CreateInstance(type); return classobj; } else System.Windows.Forms.MessageBox.Show(" 命名空间或类名错误 !"); } catch (System.NullReferenceException e) { System.Windows.Forms.MessageBox.Show(e.Message); } return (object)0; } }}
//调用
public partial class Mainform : Form { public Mainform() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { LDFS myldfs = new LDFS(); object myobj = myldfs.Invoke("Dynamic_linking.dll", "Dynamic_linking", "ShowErrorForm"); ((Form)myobj).Show(); #region --加载dll-- //利用反射进行动态加载和调用. //Assembly ass = Assembly.LoadFrom(Environment.CurrentDirectory + "//Dynamic_linking.dll"); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名 加载dll后,需要使用dll中某类. //Type type = ass.GetType("Dynamic_linking.ShowErrorForm");//利用类型的命名空间和名称获得类型 需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略 //Object obj = Activator.CreateInstance(type, null);//利用指定的参数实例话类型 //((Form)obj).Show(); //调用类型中的某个方法: //需要首先得到此方法 //MethodInfo mi = type.GetMethod("Add");//通过方法名称获得方法 //然后对方法进行调用,多态性利用参数进行控制 //object myobj = mi.Invoke(obj, new object[]{2,3});//根据参数直线方法,返回值就是原方法的返回值 #endregion }