博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c#插件式开发
阅读量:5266 次
发布时间:2019-06-14

本文共 3936 字,大约阅读时间需要 13 分钟。

接着上一篇文章:

MEF:

原文:

首先,新建一个类库,里面定义接口,这里定义两个方法,一个有返回值的,一个无返回值的。

using System;  using System.Collections.Generic;  using System.Text;    namespace IMsg {      ///      /// 这是插件必须实现的接口,也是主程序与插件通信的唯一接口      /// 换句话说,主程序只认识插件里的这些方法      ///      publicinterface IMsgPlug {  void OnShowDlg();  string OnShowInfo();      }  }
将上面的类库生成IMsg.dll, 新建一个类库MYPlugin1,添加刚出的引用,分别新建两个类来实现IMsg中定义的接口。
using System;  using System.Collections.Generic;  using System.Text;  using IMsg;  namespace MYPlugin1 {      publicclass myConsole: IMsgPlug {
#region IMsgPlug成员publicvoid OnShowDlg() { Console.WriteLine("控制台调用插件的OnShowDlg方法"); } publicstring OnShowInfo() { return "myConsole"; }#endregion } } using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using IMsg; namespace MYPlugin1 { publicclass MYDlg: Form, IMsgPlug {
#region IMsgPlug成员 publicvoid OnShowDlg() { this.Text = "插件子窗体"; this.ShowDialog(); //调用Form的ShowDialog,显示窗体 } publicstring OnShowInfo() { return "MyDlg"; }#endregion } }

 

将上面的都生成dll, 生成目录可以设置为新建exe工程的bin目录plugins文件夹下。Plugins文件夹是新建的,专门存放插件的。 新建一个 WinForm项目来使用刚才的插件.

using System;  using System.IO;  using System.Linq;  using System.Collections;  using System.Windows.Forms;  using System.Reflection;    namespace myConsole  {      public partial class Form1 : Form      {          ///           /// 应用程序的主入口点。          ///           [STAThread]          static void Main()          {              Application.EnableVisualStyles();              Application.SetCompatibleTextRenderingDefault(false);              Application.Run(new Form1());          }            public Form1()          {              InitializeComponent();          }            ///           /// 存放插件的集合          ///           private ArrayList plugins = new ArrayList();            //载入所有插件          private void btnLoadPlug_Click(object sender, EventArgs e)          {              string[] files = Directory.GetFiles(Application.StartupPath + "\\plugins");              if (files != null)                  this.listBox1.Items.Clear();                foreach (var f in files)              {                  if (!f.ToUpper().EndsWith(".DLL"))                      continue;                  try                  {                      Assembly ab = Assembly.LoadFile(f);                      Type[] t = ab.GetTypes();                      foreach (var x in t)                      {                          if (x.GetInterface("IMsgPlug") != null)                          {                              plugins.Add(ab.CreateInstance(x.FullName));                              this.listBox1.Items.Add(x.FullName);                          }                      }                  }                  catch (Exception ex)                  {                      MessageBox.Show(ex.Message);                  }              }          }            //调用插件的方法          private void btnExecute_Click(object sender, EventArgs e)          {              if (this.listBox1.SelectedIndex == -1)                  return;                object selObj = this.plugins[this.listBox1.SelectedIndex];              Type t = selObj.GetType();              MethodInfo OnShowDlg = t.GetMethod("OnShowDlg");              MethodInfo OnShowInfo = t.GetMethod("OnShowInfo");                OnShowDlg.Invoke(selObj, null);              object returnValue = OnShowInfo.Invoke(selObj, null);              this.lblMsg.Text = returnValue.ToString();          }      }  }

 

运行结果:

 

此方法用了反射,个人感觉效果不是很好。另外,注意dll对象的依赖,这种问题我在手写上面demo的时候发现了,首先要保证依赖文件的存在,再一个依赖文件的路径需要正确。另一点要说下,对反射后的验证可以做一些加强处理,listbox对象显示的名字可以通过给dll中对象添加特性标记,然后获取显示出来。下一节我们看看MEF的小例子。

最后想说一下,这不是正在意义上的插件式开发,请参阅微软的MEF和MAF的设计

 

出处:http://blog.csdn.net/joyhen/article/details/40072973

转载于:https://www.cnblogs.com/mq0036/p/7017494.html

你可能感兴趣的文章
printf格式输出知识整理
查看>>
sed 命令用法
查看>>
当DIV内出现滚动条,fixed实效怎么办?
查看>>
方维分享系统二次开发, 给评论、主题、回复、活动 加审核的功能
查看>>
Matlab parfor-loop并行运算
查看>>
Struts2 拦截器
查看>>
Oracle HRMS API's
查看>>
PostgreSQL中如何查看一个表所对应的文件
查看>>
mysql_real_escape_string() vs addslashes() vs addcslashes()
查看>>
string与stringbuilder的区别
查看>>
2012-01-12 16:01 hibernate注解以及简单实例
查看>>
iOS8统一的系统提示控件——UIAlertController
查看>>
基于visual Studio2013解决C语言竞赛题之1060寻找回文数
查看>>
几道字典树题目
查看>>
PAT甲级——1101 Quick Sort (快速排序)
查看>>
Stripe
查看>>
python创建进程的两种方式
查看>>
1.2 基础知识——关于猪皮(GP,Generic Practice)
查看>>
迭代器Iterator
查看>>
java易错题----静态方法的调用
查看>>