插件接口 计应192(西) 七组 刘俊

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

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)
{ //检索出文件名 以.dIl结束的文件
if (file.Substring(file.LastIndexOf(".")) == ".dIl")
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.FulIName));
//将该类型名载入列表框内
Listltems.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 itermStr = Listltems.Selectedltem. ToString();
if(ListItems.SelectedIndex>= 0)
{
if (itemStr == "myConsole'")
{ //调用存 储在动态数组plugins里面的插件对象的OnShowInfo方法
string msgInfo
((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowInfo();
MessageBox. Show(msgInfo, "MYPluginl", MessageBoxButtons.OK,
MessageBox Icon.Information);
}
else if (itemStr = "MYDg")//调用存储在动态数组plugins里面的插件对SÉJ OnShowDlg方法
{
((IMsgPlug)plugins[ListItems.SelectedIndex]).OnShowDlg);
}
}
else
MessageBox.Show("请先选择列表框里的插件项","Warning",
MessageBoxButtons.OK, MessageBoxIcon. Warning);
}
private void buttonl_ _Click( object sender, EventArgs е)
{
try
{/ /载入插件
LoadAllPlugins0;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
}
}
最后,编写插件类库,实现接口的属性,方法,事件。
//程序集(dII)内部的一一个类1,该类实现了插件接口

using System;
using System.Collctions.Generic;using System.Text;
using IMsg;

namespace MYPluginl
{ //实现插件接口
public class myConsole : IMsgPlug
{
public void OnShowDlg() {}
public string OnShowInfo()
{
return "调用了插件1的OnShowInfo方法!";
}
}
}
//程序集(I)内部的一一个类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 OnShowlnfo() { return null; }
public void OnShowDlg()
{
this.Show();
}
//=========================
}
}
总结:通过反射以及接口使C#下的插件编程变得容易,我们在接口中定义的字段,属性,方法,
事件是在插件里面被实现的,是在主程序里被解析的。主程序通过公共的接口访问插件。

计应192(西)

七组

刘俊

原文地址:https://www.cnblogs.com/7930li/p/14632770.html