C#_Assembly-Reflection_程序集与反射 练习<一> 记事本插件编写
2015-12-01 10:42
645 查看
//MyNotepad 为其编写插件 动态加载 听起来很niuB有木有?^_~ 下面我们就来实现这个吧!加油
//新建工程 添加窗体项目 画如下界面:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201093011968-1981720975.png)
//这里有个菜单项 以及TextBox -> Dock填充中间
//这里先实现 窗体加载时 动态加载dll(所谓的插件)到菜单栏中
//我们在Debug目录下(改目录可以修改) 创建放置我们插件的地方 就新建一个文件夹 就叫Plugins吧
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201093631187-981414818.png)
现在我们假设在Plugins文件夹中已经有了我们写好的接口文件(稍后我们再去编写这个文件)
我们在程序加载时去动态加载这个文件夹下的所有dll文件
//那我们需要什么类型呢? ---->> 使用接口来规范我们将要用的类型
好哒,我们现在在工程中添加接口文件 (其实就是添加一个类啦~)
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201095120608-892795504.png)
在IEditor.cs文件中定义我们的接口规范:
//有了接口规范 我们现在就去写我们之前假设有(实际上没有)的dll文件吧,吼吼~
添加类库,这里我们把插件实现的功能写在这个类库中 要实现我们刚才定义的接口规范 记得引用接口哟~
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201100030280-1202139346.png)
我们在使在插件中定义的类型去继承接口 :
//在主窗体中继续:
//为单击注册的事件:
ok~来运行下:发现菜单下啥都没有~
额~
因为还没把生成的插件放到文件夹下 程序找不到这个插件 自然不会去加载 二货 ^_ ~
好哒~我们来清理 重新生成下 将生成的dll文件放到主窗体中 我们定义的Plugins文件中:
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201103640358-1477747253.png)
再次运行:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202012/19/a843c4af4e6c3b47122d8673197c9cd4.png)
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201104135890-589533720.png)
噢了~
下次插件继续~
//新建工程 添加窗体项目 画如下界面:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201093011968-1981720975.png)
//这里有个菜单项 以及TextBox -> Dock填充中间
//这里先实现 窗体加载时 动态加载dll(所谓的插件)到菜单栏中
//我们在Debug目录下(改目录可以修改) 创建放置我们插件的地方 就新建一个文件夹 就叫Plugins吧
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201093631187-981414818.png)
现在我们假设在Plugins文件夹中已经有了我们写好的接口文件(稍后我们再去编写这个文件)
我们在程序加载时去动态加载这个文件夹下的所有dll文件
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { LoadPlugins(); } private void LoadPlugins() { //加载dll文件 : 1. 找到文件 2.加载 //get the directory string dPath=Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string pluginsDirectoryPath = Path.Combine(dPath, "Plugins"); //find all dll files string[] allDllFilePath = Directory.GetFiles(pluginsDirectoryPath, "*.dll"); //遍历每个dll文件 动态加载到程序集中 for (int i = 0; i < allDllFilePath.Length; i++) { Assembly assembly = Assembly.LoadFile(allDllFilePath[i].ToString()); //利用反射获取类型 Type[] types = assembly.GetTypes(); //遍历types中所有类型 找到我们所需要的类型 //那我们需要什么类型呢? } } }
//那我们需要什么类型呢? ---->> 使用接口来规范我们将要用的类型
好哒,我们现在在工程中添加接口文件 (其实就是添加一个类啦~)
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201095120608-892795504.png)
在IEditor.cs文件中定义我们的接口规范:
public interface IEditor { //定义一个只读属性 表示插件的名称 public string PluginName { get; } //运行该插件的方法 void Run(TextBox txtBox); }
//有了接口规范 我们现在就去写我们之前假设有(实际上没有)的dll文件吧,吼吼~
添加类库,这里我们把插件实现的功能写在这个类库中 要实现我们刚才定义的接口规范 记得引用接口哟~
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201100030280-1202139346.png)
我们在使在插件中定义的类型去继承接口 :
public class ToUpper:IEditor { //实现接口中定义的只读属性 string PluginName { get { return "转换大写"; } } //实现接口中定义的函数 public void Run(System.Windows.Forms.TextBox txtBox) { txtBox.Text = txtBox.Text.ToUpper(); } }
//在主窗体中继续:
//遍历每个dll文件 动态加载到程序集中 for (int i = 0; i < allDllFilePath.Length; i++) { Assembly assembly = Assembly.LoadFile(allDllFilePath[i].ToString()); //利用反射获取类型 Type[] types = assembly.GetTypes(); //那我们需要什么类型呢? //在接口中去定义 //我们期望获取的接口类型 Type IEditorType=typeof(IEditor); //遍历types中所有类型 找到我们所需要的类型 for (int j = 0; j < types.Length; j++) { //判断 1.是IEditorType的实例 2.不为抽象类型 if (IEditorType.IsAssignableFrom(types[j]) && !types[j].IsAbstract) { //找到类型之后 为接口变量 赋值 --> 实现该接口的类型的对象 IEditor ieditor = (IEditor)Activator.CreateInstance(types[j]); //将插件名称加载到该格式下拉表中 ToolStripItem tsp= MenuStripItemFormat.DropDownItems.Add(ieditor.PluginName); //为tsp注册事件 tsp.Click += tsp_Click; tsp.Tag = ieditor; } } }
//为单击注册的事件:
void tsp_Click(object sender, EventArgs e) { ToolStripItem tsp = sender as ToolStripItem; IEditor ieditor = (IEditor)tsp.Tag; if (ieditor != null) { ieditor.Run(this.textBox1); } }
ok~来运行下:发现菜单下啥都没有~
额~
因为还没把生成的插件放到文件夹下 程序找不到这个插件 自然不会去加载 二货 ^_ ~
好哒~我们来清理 重新生成下 将生成的dll文件放到主窗体中 我们定义的Plugins文件中:
jiangzi:
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201103640358-1477747253.png)
再次运行:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202012/19/a843c4af4e6c3b47122d8673197c9cd4.png)
![](http://images2015.cnblogs.com/blog/812414/201512/812414-20151201104135890-589533720.png)
噢了~
下次插件继续~
相关文章推荐
- [EmguCV][000] 基于C#搭建 Emgu CV 开发环境
- C#接口实例
- C#抽象类和抽象方法
- C#_Assembly-Reflection_程序集与反射
- C#程序调用cmd.exe执行命令
- C# 执行bat批处理文件
- C#综合揭秘——深入分析委托与事件
- C#中的Attribute
- 【C#】窗体透明度、ListBox的增删改查
- c#隐藏和重写基类方法的区别
- c# datagridview属性设置
- C#的自定义button
- c#事件(续委托之后)
- C#_FindWindow
- c# 中接口和抽象类的区别
- C# BackgroundWorker的使用
- 读取磁盘(c#流 文件)
- Couchbase 环境搭建与使用(C#)
- C# 获取文件名及扩展名
- C#基础——数据类型