zoukankan      html  css  js  c++  java
  • 反射 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
  • 相关阅读:
    vs项目属性中的包含目录和库目录以及附加依赖项全都配置正确了,却还是提示:无法解析的外部符号
    开发六年mybatisplus使用小结
    去“BAT”这样面试,拿到offer的几率是80%
    阿里P7级教你如何在Spring Boot应用程序中使用Redis
    为什么Java大数据能带你走上人生巅峰
    惊呆!Java程序员等级一览
    不要做一个只会面向搜索编程的程序员
    三年总结出来的11个JPA和Hibernate查询配置小技巧
    阿里高级架构师教你使用Spring JMS处理消息事务源码案例
    阿里高级架构师教你使用Spring Cloud Sleuth跟踪微服务
  • 原文地址:https://www.cnblogs.com/nanxiaoxiang/p/5166850.html
Copyright © 2011-2022 走看看