第一定义接口
/// <summary>
/// 这是插件必须实现的接口,也是主程序与插件通信的唯一接口
/// 换句话说,主程序只认识插件里的这些方法
///
</summary>
public interface
IMsgPlug
{
void OnShowDlg();
string
OnShowInfo();
}
定义接口是为了告诉主程序插件做事的方法
第二插件实现接口,并且实现接口的相应的方法
MyConsole实现接口的方法
public class myConsole : IMsgPlug
{
#region IMsgPlug
成员
public void
OnShowDlg()
{
Console.WriteLine("控制台调用插件的OnShowDlg方法");
}
public string
OnShowInfo()
{
return
"myConsole";
}
#endregion
}
插件二实现接口的方法,并且写出要做的事
public class MYDlg : Form, IMsgPlug
{
#region IMsgPlug
成员
public void
OnShowDlg()
{
this.Text =
"插件子窗体";
this.ShowDialog();
//调用Form的ShowDialog,显示窗体
}
public string
OnShowInfo()
{
return
"MyDlg";
}
#endregion
}
在使用插件变成的时候要使用反编译程序集,对程序集进行反编译,所以要加载或者是遍历所有编译后的文件
如下:
//定义一个数组来承载所有编译后的文件
private ArrayList plugins = new ArrayList();
//public
Form1()
//{
//
InitializeComponent();
//}
///
<summary>
///
载入所有插件
///
</summary>
private void
LoadAllPlugs()
{
//获取插件目录(plugins)下所有文件
string[] files =
Directory.GetFiles(Application.StartupPath);
foreach (string file in
files)
{
if
(file.ToUpper().EndsWith(".DLL"))
{
try
{
//载入dll 所有的程序集
Assembly ab =
Assembly.LoadFrom(file);
Type[] types =
ab.GetTypes();
foreach (Type t in
types)
{
//如果某些类实现了预定义的IMsg.IMsgPlug接口,则认为该类适配与主程序(是主程序的插件)
if (t.GetInterface("IMsgPlug") !=
null)
{
plugins.Add(ab.CreateInstance(t.FullName));
listBox1.Items.Add(t.FullName);
}
}
}
catch (Exception
ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
//加载并且把相应的插件在主程序中调用
private void btnLoadPlus_Click(object sender, EventArgs
e)
{
LoadAllPlugs();
}
//调用插件的方法
private void
btnExcute_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.lbMsg.Text =
returnValue.ToString();
}