【原创】C#插件编程(实例精析)

最近也研究了下插件编程,网上的例子太少,而且不适合初学者。这里专门做了个简单易懂的例子,供大家学习,程序如有问题还望跟帖予以指教。

       程序界面运行如下:

//==============================================================

首先,我们要定义一个插件接口,接口规范了插件内部类的程序结构,应实现的字段,属性,方法,事件。

using System;
using System.Collections.Generic;
using System.Text;

namespace IMsg
{   //这是插件必须要实现的接口,也是主程序与插件通信的唯一接口,
    //换句话说,主程序只认识插件里的这些方法

    public interface IMsgPlug
    {
        void OnShowDlg();
        string OnShowInfo();
    }
}

再者,需要实现接口在主程序内部的处理过程,包括载入插件,获取插件内部的被接口规范了的字段,属性,方法,事件。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Collections;
using IMsg;

namespace MsgBoxMain
{
    public partial class FormMain : Form
    {
        public ArrayList plugins = new ArrayList();
        public FormMain()
        {
            InitializeComponent();
        }
        //载入插件
        private void LoadAllPlugins()
        {
            //获取指定插件目录下的所有文件的文件名
            string[] files = Directory.GetFiles(Application.StartupPath + @"/plugins");
            //遍历该文件名集合
            foreach (string file in files)
            {   //检索出文件名以.dll结束的文件
                if (file.Substring(file.LastIndexOf(".")) == ".dll")
                {
                    try
                    {   //载入dll
                        Assembly ab = Assembly.LoadFile(file);
                        //获得载入的dll中的所有类
                        Type[] tempTs = ab.GetTypes();
                        //遍历该类集合
                        foreach (Type tp in tempTs)
                        {
                            //如果某些类实现了预定义的IMsg.IMsgPlug接口,则认为该类适配与主程序(是主程序的插件)
                            if (IsValidPlugin(tp))
                            {   //实例化该类,并将对象装入动态数组plugins
                                plugins.Add(ab.CreateInstance(tp.FullName));
                                //将该类型名载入列表框内
                                ListItems.Items.Add(tp.Name.ToString());
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "加载插件出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
        //判断模块的类是否满足预定义接口
        private bool IsValidPlugin(Type t)
        {
            bool ret = false;
            Type[] interfaces = t.GetInterfaces();
            foreach (Type theInterface in interfaces)
            {
                if (theInterface.FullName == "IMsg.IMsgPlug")
                {
                    ret = true;
                    break;
                }
            }
            return ret;
        }
        //调用插件内的方法
        private void button2_Click(object sender, EventArgs e)
        {  
            //获取列表框内被选择的项
            string itemStr = ListItems.SelectedItem.ToString();
            if(ListItems.SelectedIndex >= 0)
            {
                if (itemStr == "myConsole")
                {   //调用存储在动态数组plugins里面的插件对象的OnShowInfo方法
                    string msgInfo = ((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowInfo();
                    MessageBox.Show(msgInfo, "MYPlugin1", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else if (itemStr == "MYDlg")//调用存储在动态数组plugins里面的插件对象的OnShowDlg方法
                {
                    ((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowDlg();
                }
            }
            else
                MessageBox.Show("请先选择列表框里的插件项", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {   //载入插件
                LoadAllPlugins();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

最后,编写插件类库,实现接口的属性,方法,事件。

//程序集(dll)内部的一个类1,该类实现了插件接口

using System;
using System.Collections.Generic;
using System.Text;
using IMsg;

namespace MYPlugin1
{   //实现插件接口
    public class myConsole : IMsgPlug
    {  
        public void OnShowDlg() {}
        public string OnShowInfo()
        {
            return "调用了插件1的OnShowInfo方法!";
        }
    }
}

//程序集(dll)内部的一个类2,该类实现了也插件接口

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using IMsg;

namespace MYPlugin1
{   //实现插件接口
    public partial class MYDlg : Form, IMsgPlug
    {
        public MYDlg()
        {
            InitializeComponent();
        }

        //=============================================
        public string OnShowInfo() { return null; }
        public void OnShowDlg()
        {
            this.Show();
        }
        //=============================================
    }
}

总结: 通过反射以及接口使C#下的插件编程变得容易,我们在接口中定义的字段,属性,方法,事件是在插件里面被实现的,是在主程序里被解析的。主程序通过公共的接口访问插件。

源码地址:

https://download.csdn.net/download/jam12315/661564

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
c是一种编程语言,是由丹尼斯·里奇于1972年在美国贝尔实验室开发的。c语言是一种通用的、高级的、结构化的编程语言,被广泛应用于操作系统、嵌入式系统、网络驱动、游戏开发等领域。 C语言的特点主要包括以下几点: 1. 简洁高效:C语言的语法简洁,提供了丰富的语言特性,使得开发者可以用更少的代码实现更多的功能。C语言直接与计算机硬件进行交互,可以充分利用计算机资源,提高程序的执行效率。 2. 可移植性:C语言的编译器可以在不同的操作系统上运行,因此程序可以在不同的平台上进行移植。这使得C语言成为开发跨平台应用的首选语言。 3. 强大的控制结构:C语言提供了丰富的控制结构,如条件语句、循环语句、函数等,使得程序可以根据不同的条件执行不同的操作,实现复杂的逻辑控制。 4. 丰富的库函数:C语言提供了大量的库函数,包括输入输出、字符串处理、内存管理等功能,使得开发者可以更方便地完成常见的操作。同时,C语言也支持自定义函数,可以根据实际需要编写自己的函数库。 总之,C语言是一种功能强大、高效、可移植的编程语言,被广泛应用于各种领域。掌握C语言可以帮助开发者更好地理解计算机底层原理,提高程序的执行效率,实现复杂的功能。因此,学习C语言对于计算机科学专业的学生以及从事软件开发工作的人来说是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jamie.T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值