外掛式架構,一種全新的、開放性的、高擴充套件性的架構體系。外掛式架構設計好處很多,把擴充套件功能從框架中剝離出來,降低了框架的複雜度,讓框架更容易實現。擴充套件功能與框架以一種很鬆的方式耦合,兩者在保持介面不變的情況下,可以獨立變化和釋出。基於外掛設計並不神祕,相反它比起一團泥的設計更簡單,更容易理解。
書寫4個外掛類庫,分別傳參實現「加減乘除」運算,呼叫外掛的使用者端採用Winform表單程式。
目標框架:.NET Framework 4.6.1
專案架構和表單佈局:
使用者端程式:
外掛描述:
/// <summary>
///外掛基礎類別
/// </summary>
public abstract class Base
{
/// <summary>
/// 外掛名稱
/// </summary>
/// <returns></returns>
public abstract string Name();
/// <summary>
/// 外掛描述
/// </summary>
/// <returns></returns>
public abstract string Desc();
/// <summary>
/// 執行方法
/// </summary>
/// <param name="param1">引數1</param>
/// <param name="param2">引數2</param>
/// <returns></returns>
public abstract string Run(int param1, int param2);
/// <summary>
/// 版本
/// </summary>
public string Version
{
get { return "1.0.0"; }
}
}
public class PlugInA: Base
{
public override string Name()
{
return "PlugInA";
}
public override string Desc()
{
return "加法";
}
public override string Run(int param1,int param2)
{
return (param1 + param2) + "";
}
}
}
public class PlugInB : Base
{
public override string Name()
{
return "PlugInB";
}
public override string Desc()
{
return "減法";
}
public override string Run(int param1, int param2)
{
return (param1 - param2) + "";
}
}
public class PlugInC : Base
{
public override string Name()
{
return "PlugInC";
}
public override string Desc()
{
return "乘法";
}
public override string Run(int param1, int param2)
{
return (param1 * param2) + "";
}
}
public class PlugInD : Base
{
public override string Name()
{
return "PlugInD";
}
public override string Desc()
{
return "除法";
}
public override string Run(int param1, int param2)
{
return (param1 / param2) + "";
}
}
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
dgrvPlugins.AutoGenerateColumns = false;
}
List<PluginModel> List = new List<PluginModel>();
readonly string PlugInPath = Application.StartupPath + "\\PlugIns";
/// <summary>
/// 載入外掛
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btLoadPlugins_Click(object sender, EventArgs e)
{
if (!Directory.Exists(PlugInPath))
{
Directory.CreateDirectory(PlugInPath);
}
List.Clear();
string[] files = Directory.GetFiles(PlugInPath);
foreach (string file in files)
{
if (file.ToLower().EndsWith(".dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(file);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.BaseType.FullName == "PlugInBase.Base")
{
object obj = assembly.CreateInstance(type.FullName);
string name = type.GetMethod("Name").Invoke(obj, null).ToString();
string desc = type.GetMethod("Desc").Invoke(obj, null).ToString();
string version = type.GetProperty("Version").GetValue(obj).ToString();
List.Add(new PluginModel
{
Name = name,
Desc = desc,
Version = version,
type = type,
Obj = obj
});
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
dgrvPlugins.DataSource = new BindingList<PluginModel>(List);
}
/// <summary>
/// 開啟外掛目錄
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btOpenPluginDir_Click(object sender, EventArgs e)
{
Process.Start(PlugInPath);
}
/// <summary>
/// 執行選中外掛
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btExcute_Click(object sender, EventArgs e)
{
//獲取選擇的外掛資訊
int index = dgrvPlugins.CurrentRow.Index;
object obj = List[index].Obj;
Type type = List[index].type;
//引數
object[] inParams = new object[2];
inParams[0] =Convert.ToInt32( dgrvPlugins.CurrentRow.Cells[2].Value);
inParams[1] = Convert.ToInt32(dgrvPlugins.CurrentRow.Cells[3].Value);
object value = type.GetMethod("Run").Invoke(obj, inParams);
MessageBox.Show(Convert.ToString(value),"結果",MessageBoxButtons.OK);
}
}
編譯生成專案的時候需要注意,此處的呼叫外掛是通過反射呼叫.dll中類和方法,所以首先要找到這個.dll的檔案,所以此處我們在Winform使用者端程式下建立一個存放類庫dll的檔案PlugIns
,在外掛類庫專案生成後事件命令中,填入如下命令:
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)\PlugIns"
以上命令代表,在專案的類庫生成後,將類庫copy到解決方案的路徑子資料夾PlugIns
,也就是我們建立存放自定義外掛的資料夾。當然,如果不怕麻煩,每次生成後,手動複製到此資料夾也可以,直接複製到使用者端程式的..\bin\PlugIns
資料夾下。
全選這些類庫,把這些類庫設定為"如果較新則複製",這樣每次在編譯使用者端程式,如果自定義外掛有更新,則同步會複製到bin
目錄下
外掛基礎類別提供了規範,需要在類庫的生成後事件,新增命令:
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)\bin\Debug"
將生成的dll檔案,拷貝到使用者端程式的bin
路徑下
每一個外掛被編譯成了dll,各模組無法單獨執行,必須依託於主程式。
修改外掛時,由於生成的是dll,無法快速直觀的檢視修改以及偵錯。
每一個外掛必須依賴於某一個規範。
本文來自部落格園,作者:碼農阿亮,轉載請註明原文連結:https://www.cnblogs.com/wml-it/p/17706182.html