反射 type 的基本用法,动态加载插件
这里介绍反射的简单实用
MyClass类
1 public class MyClass 2 { 3 public int Age { get; set; } 4 public string Name { get; set; } 5 6 public MyClass() 7 { 8 Console.WriteLine("无参数的构造函数"); 9 } 10 11 public MyClass(string name) 12 { 13 this.Name = name; 14 Console.WriteLine("有参数的构造函数"); 15 } 16 17 public string GetUpperString(string str) 18 { 19 return str.ToUpper(); 20 } 21 22 private void PrivateMethod() 23 { 24 Console.WriteLine("PrivateMethod"); 25 } 26 }
Type typeof
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Type typeMyClass = typeof(MyClass); 6 7 //获取方法 8 MethodInfo methodinfo = typeMyClass.GetMethod("GetUpperString"); 9 object result = methodinfo.Invoke(Activator.CreateInstance(typeMyClass), new object[] { "namesss to upper" }); 10 Console.WriteLine(result);//NAMESSS TO UPPER 11 12 //调用有参数的构造函数 13 ConstructorInfo ctorInfo = typeMyClass.GetConstructor(new Type[] { typeof(string) }); 14 //ctorResult 是MyClass 对象 15 object ctorResult = ctorInfo.Invoke(new object[] { "namess" }); 16 Console.WriteLine(ctorResult);//反射3.Myclass 17 18 //获得 属性 19 PropertyInfo pInfo = typeMyClass.GetProperty("Name"); 20 object names = pInfo.GetValue(Activator.CreateInstance(typeMyClass)); 21 Console.WriteLine(names); 22 23 PropertyInfo[] pinfos = typeMyClass.GetProperties(); 24 25 Console.Read(); 26 } 27 }
动态加载程序集
Assembly assembly = Assembly.LoadFile(""); Type[] types = assembly.GetTypes(); ///获得指定的类型 Type type = assembly.GetType("空间名.类名"); //这里是找方法名是MethodName,私有的 或者静态的方法 MethodInfo minfo= typeMyClass.GetMethod("MethodName", BindingFlags.NonPublic | BindingFlags.Static);
2.反射还有一个作用,动态加载插件
要实现插件功能,首先 原程序要有一个接口,来规范插件
插件的接口IMyNoteExeInfer dll代码是
1 namespace MyNotePadExeInfer 2 { 3 /// <summary> 4 /// 接口默认不是public 5 /// </summary> 6 public interface IMyNoteExeInfer 7 { 8 9 /// <summary> 10 /// 插件的名称 11 /// </summary> 12 string name 13 { 14 get; 15 set; 16 } 17 /// <summary> 18 /// 运行插件 19 /// </summary> 20 /// <param name="txt">textbox的插件</param> 21 void Run(TextBox txt); 22 } 23 }
接着是 原程序要根据接口,动态加载(未来未知的)插件
1 private void Form1_Load(object sender, EventArgs e) 2 { 3 //加载插件 4 //1. 找到多个控件的文件路径 5 Assembly ass = Assembly.GetExecutingAssembly(); 6 ///规定好把插件放到执行目录的 addnotedll文件夹中 7 string pathfile = Path.Combine(Path.GetDirectoryName(ass.Location), "addnotedll"); 8 //找到每个插件的绝对路径 9 string[] filePaths = Directory.GetFiles(pathfile, "*.dll"); 10 foreach (string fileP in filePaths) 11 { 12 Assembly oneAssmebly = Assembly.LoadFrom(fileP); 13 Type[] types = oneAssmebly.GetExportedTypes();//获得程序集中的public 类型 14 //规范插件的接口IMyNoteExeInfer 15 Type typeNoteInfer = typeof(IMyNoteExeInfer); 16 for (int i = 0; i < types.Length; i++) 17 { 18 //挑取实现了接口IMyNoteExeInfer的类型 19 if (typeNoteInfer.IsAssignableFrom(types[i]) && !types[i].IsAbstract) 20 { 21 //创建当前类型的实例 22 IMyNoteExeInfer currDllInstance = (IMyNoteExeInfer)Activator.CreateInstance(types[i]); 23 24 //在工具下拉单toolSmiSet中 加入控件 25 ToolStripItem newAdditem= toolSmiSet.DropDownItems.Add(currDllInstance.name); 26 newAdditem.Tag = currDllInstance;//把插件对象传过去,这样在那里就可以用对象调方法了 27 //给新增加的下拉单 注册单击事件 28 newAdditem.Click +=newAdditem_Click; 29 } 30 } 31 32 } 33 34 } 35 36 private void newAdditem_Click(object sender, EventArgs e) 37 { 38 //sender就是单击的下拉单 39 ToolStripItem newitem = (ToolStripItem)sender; 40 //newitem.Tag传过来的是对象 插件的对象 41 //因为插件对象都继承接口,所以可以直接用接口接受 42 IMyNoteExeInfer iexeInfer= (IMyNoteExeInfer)newitem.Tag; 43 iexeInfer.Run(textBox1);//运行插件 44 }
下面是插件的dll代码
1 public class MyNoteToUpper : IMyNoteExeInfer 2 { 3 /// <summary> 4 /// 运行插件 5 /// </summary> 6 /// <param name="txt"></param> 7 public void Run(TextBox txt) 8 { 9 txt.Text = txt.Text.ToUpper(); 10 11 } 12 private string _name; 13 /// <summary> 14 /// 插件的名字 15 /// </summary> 16 public string name 17 { 18 get { return "ToUpper"; } 19 set { _name = value; } 20 } 21 }