該例通過反射加載plugins文件夾下實現了IEditor接口的dll插件程序集。其中IEditor接口單獨寫在一個類庫中。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//1、檢查plugins目錄下是否有dll文件
//1.1獲取當前執行的exe文件的絕對路徑
string exePath = Assembly.GetExecutingAssembly().Location;
//獲取插件的目錄路徑
string pluginsPath = Path.Combine(Path.GetDirectoryName(exePath), "plugins");
//2、如果有dll文件,則循環遍歷,將每個dll文件都通過Assembly.LoadFile()加載起來,然後獲取dll程序集中的類型。
//2.1搜索pluginsPath目錄下是否有對應的dll文件
//返回值是一個string數組,裏面存儲這每個dll文件的完整路徑
string[] dlls = Directory.GetFiles(pluginsPath, "*.dll");//注意是“dll”程序集
//循環遍歷把每個插件都加載起來
foreach (string item in dlls)
{
//獲取當前插件(程序集),這裏的每個item就是一個dll的完整路徑
Assembly asem = Assembly.LoadFile(item);
//遍歷asem這個插件(程序集)中的每個類型,找到那些public類型,並且是實現了IEditor接口的那些類
//獲取所有public類型
Type[] types = asem.GetExportedTypes();
//獲得接口的Type
Type typIEditor = typeof(IEditor);
//遍歷每個類型看看這個類型是否實現了IEditor接口的類型
foreach (Type typeClass in types)
{
//2、判斷這個類型是否實現了IEditor接口而且可以被實例化,否則不能用
if (typIEditor.IsAssignableFrom(typeClass)&&!typeClass.IsAbstract)
{
//創建一個typeClass類型的對象
IEditor editor = (IEditor)Activator.CreateInstance(typeClass);
//在菜單欄中將該插件的名字加進去
ToolStripItem tsiMenu = this.格式ToolStripMenuItem.DropDownItems.Add(editor.PluginName);
tsiMenu.Tag = editor;//將插件放到Tag中
//爲tsiMenu註冊單擊事件
tsiMenu.Click += new EventHandler(tsiMenu_Click);
}
}
}
}
//新增插件菜單項的單擊事件
void tsiMenu_Click(object sender, EventArgs e)
{
//sender就是當前單擊的菜單項
ToolStripItem tsi = (ToolStripItem)sender;
IEditor editor = (IEditor)tsi.Tag;
editor.StartProgram(textBox1);
}
}
public interface IEditor
{
///<summary>
///是一個只讀屬性,裏面存儲的是插件名稱
///</summary>
string PluginName
{
get;
}
//啓動插件
void StartProgram(TextBox txtBox);
}