using System;
using System.Collections.Generic;
using System.Text;
namespace IMsg {
///
/// 这是插件必须实现的接口,也是主程序与插件通信的唯一接口
/// 换句话说,主程序只认识插件里的这些方法
///
publicinterface IMsgPlug { void OnShowDlg(); string OnShowInfo();
}
}
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
}
}
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();
}
}
}
namespace PluginInterface
{
public interface IPlugin
{
string Show();
}
}
//插件A
namespace PluginA
{
public class PluginA:IPlugin
{
public string Show()
{
return "插件A";
}
}
}
//插件B
namespace PluginB
{
public class PluginB : IPlugin
{
public string Show()
{
return "插件B";
}
}
}
新建一个控制台程序,需要引用定义插件接口的dll,生成之后,需要在exe所在的目录里建一个Plugins子文件夹,将上面生成的PluginA.dll,和PluginB.dll拷贝进去。
namespace ConsolePluginTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
List pluginpath = p.FindPlugin();
pluginpath = p.DeleteInvalidPlungin(pluginpath);
foreach (string filename in pluginpath)
{
try
{
//获取文件名
string asmfile = filename;
string asmname = Path.GetFileNameWithoutExtension(asmfile);
if (asmname != string.Empty)
{
// 利用反射,构造DLL文件的实例
Assembly asm = Assembly.LoadFile(asmfile);
//利用反射,从程序集(DLL)中,提取类,并把此类实例化
Type[] t = asm.GetExportedTypes();
foreach (Type type in t)
{
if (type.GetInterface("IPlugin") != null)
{
IPlugin show = (IPlugin)Activator.CreateInstance(type);
Console.Write(show.Show());
}
}
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}
//查找所有插件的路径
private List FindPlugin()
{
List pluginpath = new List();
try
{
//获取程序的基目录
string path = AppDomain.CurrentDomain.BaseDirectory;
//合并路径,指向插件所在目录。
path = Path.Combine(path,"Plugins");
foreach (string filename in Directory.GetFiles(path, "*.dll"))
{
pluginpath.Add(filename);
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
return pluginpath;
}
//载入插件,在Assembly中查找类型
private object LoadObject(Assembly asm, string className, string interfacename
, object[] param)
{
try
{
//取得className的类型
Type t =asm.GetType(className);
if (t == null
|| !t.IsClass
|| !t.IsPublic
|| t.IsAbstract
|| t.GetInterface(interfacename) == null
)
{
return null;
}
//创建对象
Object o = Activator.CreateInstance(t,param);
if (o == null)
{
//创建失败,返回null
return null;
}
return o;
}
catch
{
return null;
}
}
//移除无效的的插件,返回正确的插件路径列表,Invalid:无效的
private List DeleteInvalidPlungin(List PlunginPath)
{
string interfacename = typeof(IPlugin).FullName;
List rightPluginPath = new List();
//遍历所有插件。
foreach (string filename in PlunginPath)
{
try
{
Assembly asm = Assembly.LoadFile(filename);
//遍历导出插件的类。
foreach (Type t in asm.GetExportedTypes())
{
//查找指定接口
Object plugin = LoadObject(asm,t.FullName,interfacename,null);
//如果找到,将插件路径添加到rightPluginPath列表里,并结束循环。
if (plugin != null)
{
rightPluginPath.Add(filename);
break;
}
}
}
catch
{
throw new Exception(filename+"不是有效插件");
}
}
return rightPluginPath;
}
}
}