专栏首页静心物语313的Coding反射案例——记事本插件练习

反射案例——记事本插件练习

编写记事本插件,实现点击视图选项卡下的小写转大写插件,实现转换功能!

准备如下:

1、记事本程序集 .exe 和 建的 lib文件夹(存.dll程序集)放在是一个位置的。
2、搜索程序集.dll文件,就会用到“反射”,导入命名空间 using System.Reflection;
3、获取包括当前程序集的完整的路径:
    Assembly.GetExecutingAssembly().Location; 
4、找到这个路径下的程序集所在的文件夹Debug。
5、用Path.GetDirectoryName( )获得当前程序集所在的文件夹;
6、Path.Combine(程序集所在的路径 , "lib")将lib进行拼接!
7、那么,现在在这个文件夹下搜索*.dll文件。
    Directory.GetFiles(程序集所在的路径,“*.dll”)
8、遍历这些程序集,看哪个实现了。这个借口规范!!!
9、获取Type....相当于获取了类的Type。
10、看这些Type是否实现了我插件的规范,,这里用接口的 方式,命名规范!!!
11、所以在主程序里边要定义一个接口,写插件的人,写的插件也要满足定义的接口!!!
12、右键“解决方案”添加一个类库 命名:记事本.Editplus .
13、删掉自带的类。Class1.cs右键。记事本.Editplus添加接口,(接口可以命名规范)命名为:
    IEditplus    F6生成!
14、在接口里定义:
    //插件的功能的名字(功能的名字是不需要改动的,所以直接用Set,不要Get)
    加载的时候,将功能的名字,加载出来,放到菜单下边就ok!
     string Name{get;};
    //改变文本框中的内容
    string ChangString(TextBox tb);//将整个文本框拿到!
    //发现没有,添加引用 右键“引用”。net下边的System.Windows.Forms,
15、  鼠标放在TextBox   Shift+Alt+F10导入命名空间!!引入命名空间,,using Systrm.Windows.Forms
16、 接口就定义好了。
    1)可以将插件的名字命名
    2)可以改变文本的内容
17、接下来,1)、写插件的人要满足这个定义的接口。
        2)、记事本这个主程序集也要满足,这个接口,(应为程序在运行的时候搜索插件,看是否是,满足定义的插件接口规范,所以要引入这个接口规范)
18、返回主程序。Form.cs,添加引用,浏览---》,记事本.Editplus.dll这个程序集
19、导入命名空间  ---->记事本.Editplus;
20、从lib文件夹下进行遍历,对每个程序集获得的Type(类)集合
    Type[] tps=ass.GetTypes();
21、拿到接口 IEditplus 这个接口的名字,(把接口看做是类(如果不好理解))
    typeof() 就是拿到这个接口的名字 
    IeditType就是这个接口名字的”“别称”“
22、Type[] tps=ass.GetTypes();就是一些类打包成了一个程序集dll文件
23、对单个的tps程序集遍历,获得其中的每个类。。
24、查看每个类,是否是实现接口IeditType这个规范,并且这个类不是抽象的类
    if(IeditType.IsAssignableFrom(tps[j]&&!tps[j].IsAbstract))
    如果是实现了这个接口,就把这个类转化为我这个接口的类型
    IEditplus iedit=(IEditplus )Activator.CreateInstance(tps[j]);//把对象tps[j]创建对象,也可以说是创建了tps实例
    创建了实例,就可以拿这个类名字这个方法了string Name{get;}
25、给窗体的菜单中的“视图”这个Name属性,赋值TSM.....利用
    TSM.DropDownItems.属性,进行添加插件的名字
    TSM.DropDownItems.Add(iedit.Name);//这里就可以调用满足接口类的,并且是实例化后,属性  属性也是方法
26、编写插件

1、Form1代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;//
using System.IO;
using 记事本Editplus;//引入命名空间
namespace 反射_记事本案例
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            ////窗体加载的时候找 程序集,所在目录的文件 搜索dll文件
            //string path=Assembly.GetExecutingAssembly().Location;
            //string path1 = Path.GetDirectoryName(path);//找到这个路径下的程序集所在的文件夹Debug。
            //string path2=Path.Combine(path1, "lib");//Path.Combine(程序集所在的路径 , "lib")将lib进行拼接!
            ////MessageBox.Show(path2);
            string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lib");
            //查找这个文件夹中是。dll结尾的文件,并返回一个数组
            string[] files=Directory.GetFiles(path,"*.dll");
            //遍历这个程序集数组
            for (int i = 0; i < files.Length; i++)
            {
                //加载程序集
                Assembly ass= Assembly.LoadFile(files[i]);
                //获取这个程序集中的所有类
                Type[] tps=ass.GetTypes();
                //
                //现在取得接口,将获得的类,进行对比,看是否符合接口规范!
                Type IeditTyep=typeof(IEditplus);//获取接口这个“类”的名字 
                //
                //开始做逐个比较是否符合规范
                for (int j = 0; j < tps.Length; j++)
                {
                    //该Type(类)是否实现接口 tps[j]是否是IeditType的实例....并且tps[j]不是抽象的类
                    if (IeditTyep.IsAssignableFrom(tps[j])&&!tps[i].IsAbstract)
                    {
                        //如果是实现了这个接口,就把这个类转化为我这个接口的类型
                        IEditplus iedit = (IEditplus)Activator.CreateInstance(tps[j]);////把对象tps[j]创建对象
                                                                                    //,也可以说是创建了tps实例
                        //显示插件的功能
                      ToolStripItem tsi= TSM.DropDownItems.Add(iedit.Name);
                       //对tsi这个对象,注册一个事件
                      tsi.Tag = iedit;//接口存起来
                      tsi.Click += tsi_Click;
                    }
                }
            }

        }
        void tsi_Click(object sender, EventArgs e)
        {
            ToolStripItem tsi = sender as ToolStripItem;
            IEditplus iedit = tsi.Tag as IEditplus;
           textBox1.Text= iedit.ChangString(textBox1);//主程序写完
        }
      
    }
}

2、定义一个接口规范:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;//

namespace 记事本Editplus
{
    //公共的public 定义规范
    public interface IEditplus
    {
        /// <summary>
        /// //插件的功能的名字(功能的名字是不需要改动的,所以直接用Get,不要Set)
        /// </summary>
        string Name{get;}
        /// <summary>
        /// //改变文本框中的内容
        /// </summary>
        /// <param name="tb"></param>
        /// <returns></returns>
        string ChangString(TextBox tb);//将整个文本框拿到!
    }
}

3、写一个小写转换大写的插件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 记事本Editplus;//
using System.Windows.Forms;///
namespace 小写转大写
{
    public  class ChangeStr:IEditplus// 满足接口的规范  //Shtit Alt F10  实现接口
    {
        string IEditplus.ChangString(System.Windows.Forms.TextBox tb)//这里提示导入命名空间
        {
            return tb.Text.ToUpper();
        }
        string IEditplus.Name
        {
            get { return "小写转大写"; }
        }
    }
} 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 委托————窗体之间传值练习------引出事件的概念

    练习:新建连个窗体,当点击Form1窗体的“传过去”,文本内容就显示在了,第二个窗体中;当点击第二个窗体时候,值又返回到窗体1的文本框中!

    静心物语313
  • 事件与委托的区别就是“+=”和“-="?

    事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或 -= 来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)

    静心物语313
  • 事件_窗体传值(使用系统自带的委托)

    本实验的目的:利用系统自带的EventHandler 委托。模仿.netFrame系统的委托是如何实现功能的;

    静心物语313
  • telerik upload 在silv

    打开SL工程添加引用Telerik.Windows.Controls.dll and Telerik.Windows.Controls.Input.dll. ...

    py3study
  • 委托(一个主窗体统计多个从窗体的按钮单击的次数)

      最近在学习金老师的《.NET2.0面向对象编程揭秘》,学到了13章,委托、事件驱动和异步调用。书上有个试一试,要求:利用委托,达到一个主窗体统计多个从窗体...

    八哥
  • WCF系列教程之WCF服务宿主与WCF服务部署

    本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆。 一、简介 任何一个程序...

    郑小超.
  • Jquery ajax传递复杂参数给WebService

    http://www.cnblogs.com/kingge/archive/2011/08/04/2127642.html

    跟着阿笨一起玩NET
  • IDEA-配置Scala语言开发

    或者: 文件->settings->pulgins 这里也能找到插件安装的位置

    cwl_java
  • 【Node.js】理解事件循环机制

    注意,上图的EVENT_QUEUE 给人看起来是只有一个队列, 根据Node.js官方介绍, EventLoop有6个阶段, 同时每个阶段都有对应的一个先进先出...

    前端博客 : alili.tech
  • 设计模式之备忘录模式

    备忘录模式(Momento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保...

    Dylan Liu

扫码关注云+社区

领取腾讯云代金券