C#_Assembly-Reflection_程序集与反射 练习<一> 记事本插件编写

//MyNotepad  为其编写插件 动态加载  听起来很niuB有木有?^_~  下面我们就来实现这个吧!加油

//新建工程 添加窗体项目 画如下界面:

//这里有个菜单项  以及TextBox -> Dock填充中间

//这里先实现 窗体加载时  动态加载dll(所谓的插件)到菜单栏中  

//我们在Debug目录下(改目录可以修改) 创建放置我们插件的地方 就新建一个文件夹  就叫Plugins吧

jiangzi:

  

现在我们假设在Plugins文件夹中已经有了我们写好的接口文件(稍后我们再去编写这个文件)

我们在程序加载时去动态加载这个文件夹下的所有dll文件 

 1  public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         private void Form1_Load(object sender, EventArgs e)
 9         {
10             LoadPlugins();
11         }
12         private void LoadPlugins()
13         {
14            
15             //加载dll文件  : 1. 找到文件    2.加载
16 
17             //get the directory
18             string dPath=Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
19 
20             string pluginsDirectoryPath = Path.Combine(dPath, "Plugins");
21 
22             //find all dll files
23             string[] allDllFilePath = Directory.GetFiles(pluginsDirectoryPath, "*.dll");
24 
25             //遍历每个dll文件  动态加载到程序集中
26             for (int i = 0; i < allDllFilePath.Length; i++)
27             {
28                 Assembly assembly = Assembly.LoadFile(allDllFilePath[i].ToString());
29                 //利用反射获取类型
30                 Type[] types = assembly.GetTypes();
31                 //遍历types中所有类型  找到我们所需要的类型
32                 //那我们需要什么类型呢?
33             }
34         }
35     }

//那我们需要什么类型呢?   ---->>  使用接口来规范我们将要用的类型

好哒,我们现在在工程中添加接口文件 (其实就是添加一个类啦~)

jiangzi:

在IEditor.cs文件中定义我们的接口规范:

 1  public interface IEditor
 2     {
 3         //定义一个只读属性   表示插件的名称
 4         public string PluginName
 5         {
 6             get;
 7         }
 8         //运行该插件的方法
 9         void Run(TextBox txtBox);
10     }

//有了接口规范  我们现在就去写我们之前假设有(实际上没有)的dll文件吧,吼吼~

添加类库,这里我们把插件实现的功能写在这个类库中  要实现我们刚才定义的接口规范   记得引用接口哟~

jiangzi:

我们在使在插件中定义的类型去继承接口 :

 1   public class ToUpper:IEditor
 2     {
 3         //实现接口中定义的只读属性
 4         string PluginName
 5         {
 6             get { return "转换大写"; }
 7         }
 8 
 9         //实现接口中定义的函数
10         public void Run(System.Windows.Forms.TextBox txtBox)
11         {
12             txtBox.Text = txtBox.Text.ToUpper();
13         }
14     }

//在主窗体中继续:

 1   //遍历每个dll文件  动态加载到程序集中
 2             for (int i = 0; i < allDllFilePath.Length; i++)
 3             {
 4                 Assembly assembly = Assembly.LoadFile(allDllFilePath[i].ToString());
 5                 //利用反射获取类型
 6                 Type[] types = assembly.GetTypes();
 7 
 8                 //那我们需要什么类型呢?   //在接口中去定义
 9 
10                 //我们期望获取的接口类型
11                 Type IEditorType=typeof(IEditor);
12 
13                 //遍历types中所有类型  找到我们所需要的类型
14                 for (int j = 0; j < types.Length; j++)
15                 {
16                     //判断        1.是IEditorType的实例     2.不为抽象类型
17                     if (IEditorType.IsAssignableFrom(types[j]) && !types[j].IsAbstract)
18                     {
19                         //找到类型之后   为接口变量 赋值  --> 实现该接口的类型的对象
20                         IEditor ieditor = (IEditor)Activator.CreateInstance(types[j]);
21 
22                         //将插件名称加载到该格式下拉表中
23                         ToolStripItem tsp= MenuStripItemFormat.DropDownItems.Add(ieditor.PluginName);
24 
25                         //为tsp注册事件
26                         tsp.Click += tsp_Click;
27                         tsp.Tag = ieditor;
28                     }
29                 }
30             }

//为单击注册的事件:

1    void tsp_Click(object sender, EventArgs e)
2         {
3             ToolStripItem tsp = sender as ToolStripItem;
4             IEditor ieditor = (IEditor)tsp.Tag;
5             if (ieditor != null)
6             {
7                 ieditor.Run(this.textBox1);       
8             }
9         }

ok~来运行下:发现菜单下啥都没有~   

额~

因为还没把生成的插件放到文件夹下  程序找不到这个插件  自然不会去加载    二货  ^_ ~

好哒~我们来清理  重新生成下  将生成的dll文件放到主窗体中 我们定义的Plugins文件中:

jiangzi:

再次运行: 

 

噢了~ 

下次插件继续~

 

posted on 2015-12-01 10:42  许清池  阅读(357)  评论(0编辑  收藏  举报

导航