先創建下圖的一個窗體,插件下沒添加項目,是留給反射加載.dll插件的。在debug目錄下加一個Plugin文件夾,將插件的.dll文件放在此文件夾下可以生效。
給方案添加一個單獨的項目來寫規範插件的接口,因爲需要生成一個.dll給寫插件的人調用
接口的代碼如下:
using System.Windows.Forms;
namespace NotePad.PluginInterface
{
public delegate TextBox GetTextBoxDelegate();
public interface NotePadPluginInterface
{
//string Name { get; }
//void Run(System.Windows.Forms.TextBox textBox);
//這個接口可以只要表示插件名稱Name屬性,和功能的Run(Textbox textbox)的方法,
//在主程序根據Name生成ToolStripMenuItem,並綁定事件,然後執行Run。
//但是把ToolStripMenuItem給接口,插件可以實現更復雜的ToolStripMenuItem
ToolStripMenuItem[] Items
{
get;
set;
}
TextBox textbox
{
get;
set;
}
event GetTextBoxDelegate GetTextBoxEvent;//用來獲取當前的textbox
void Initize();//生成ToolStripMenuItem,並綁定事件等。
}
}
窗體加載插件的代碼
using NotePad.PluginInterface;
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace NotePad
{
public partial class NotePad : Form
{
public NotePad()
{
InitializeComponent();
}
private void NotePad_Load(object sender, EventArgs e)
{
string path = Assembly.GetExecutingAssembly().Location;
string addtions = Path.Combine(Path.GetDirectoryName(path), "Plugin");
string[] dlls = Directory.GetFiles(addtions, "*.dll");//獲取插件.dll文件
foreach (string dll in dlls)
{
Assembly assenmbly = Assembly.LoadFile(dll);//加載指定路徑上的程序集文件的內容
Type[] types = assenmbly.GetExportedTypes();//獲取此程序集中定義的Public類型
Type typeNotePadExtInterface = typeof(NotePadPluginInterface);
foreach (Type type in types)
{
//驗證類型實現了NotePadExtInterface接口並且可以實例化
if (typeNotePadExtInterface.IsAssignableFrom(type) && !type.IsAbstract)
{
NotePadPluginInterface notePadEx = (NotePadPluginInterface)Activator.CreateInstance(type);//創建插件實例
notePadEx.Initize();//先初始化插件裏的Item
this.PluginToolStripMenuItem.DropDownItems.AddRange(notePadEx.Items);//將插件裏定義的Item加爲窗體 "插件"項的子項
notePadEx.GetTextBoxEvent += NotePadEx_GetTextBoxEvent;
}
}
}
}
private TextBox NotePadEx_GetTextBoxEvent()
{
return textBox1;
}
}
}
寫插件
在插件的項目裏引用規範插件的接口的程序集
插件的代碼如下:
using NotePad.PluginInterface;
using System;
using System.Windows.Forms;
namespace NotePadPlugin
{
public class NotePadPlugin: NotePadPluginInterface
{
public ToolStripMenuItem[] Items
{
get;
set;
}
public TextBox textbox
{
get;
set;
}
public event GetTextBoxDelegate GetTextBoxEvent;
public void Initize()
{
ToolStripMenuItem switchCaseItem = new ToolStripMenuItem();
switchCaseItem.Text = "切換大小寫";
ToolStripMenuItem ToUpperItem = new ToolStripMenuItem();
ToUpperItem.Text = "大寫";
ToUpperItem.Click += ToUpperItem_Click;
ToolStripMenuItem ToLowerItem = new ToolStripMenuItem();
ToLowerItem.Text = "小寫";
ToLowerItem.Click += ToLowerItem_Click;
switchCaseItem.DropDownItems.AddRange(new ToolStripMenuItem[] { ToUpperItem, ToLowerItem });
ToolStripMenuItem clearTextItem = new ToolStripMenuItem();
clearTextItem.Text = "清空";
clearTextItem.Click += ClearText_Click;
ToolStripMenuItem colorItem = new ToolStripMenuItem();
colorItem.Text = "顏色";
colorItem.Click += ColorItem_Click; ;
Items = new ToolStripMenuItem[] { switchCaseItem, clearTextItem,colorItem };
}
private void ColorItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
using (ColorDialog colorDialog = new ColorDialog())
{
if (colorDialog.ShowDialog() == DialogResult.OK)
{
textbox.ForeColor = colorDialog.Color;
}
}
}
private void ClearText_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = "";
}
private void ToLowerItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = textbox.Text.ToLower();
}
private void ToUpperItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = textbox.Text.ToUpper();
}
}
}
將插件的項目生成的dll文件放在NotePad程序Plugin文件夾下之後,運行程序可以看到插件下多了子項,而且功能都實現了。