反射 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     }
View Code

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     }
View Code

动态加载程序集 

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 }
View Code

接着是 原程序要根据接口,动态加载(未来未知的)插件

 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         }
View Code

下面是插件的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     }
View Code

 

posted @ 2016-01-28 16:50  南潇湘  阅读(321)  评论(1编辑  收藏  举报