承上一節探討,上一節是以抽換模組的狀況下模擬,模組仍依照介面定義的功能來實作。
如果能由外部擴充功能,擴充 "額外" 功能,且是非繼承必須改寫的任何功能。
某些需求情境是可以指定執行這些外部的擴充功能,是否也是有一條路可以實行?
這邊來進行實驗。
準備 .net core 專案要參考的外部 MyDLL1 專案與其類別:
namespace MyDLL1
{
public partial class Demo
{
public string toString()
{
return "this is MyDLL1 toString Method!";
}
}
}
於另一個外部專案 ExtendDLL 中加入類別:
namespace MyDLL1
{
public partial class Demo
{
ArrayList arySettingList = new ArrayList();
public void ExecServiceSetting(string HeadStyle, string BodyStyle)
{
arySettingList.Add(new { head = HeadStyle, body = BodyStyle });
}
List<double> ImportantInfo = new List<double>();
public void SavePriceRecord(double price)
{
ImportantInfo.Add(price);
}
}
}
於 .net core 專案 準備好 json 檔案,指定讀取DLL路徑與執行函式、參數內容:
{
"DLLPath": "D:\\OutSideDLLPartialClassEx\\ExtendDLL\\bin\\Debug\\ExtendDLL.dll",
"DLLModule": "MyDLL1.Demo",
"Services": [
{
"Method": "ExecServiceSetting",
"Parameter": {
"HeadStyle": {
"value": "deepDarkStyle",
"type": "string"
},
"BodyStyle": {
"value": "gentleStyle",
"type": "string"
}
}
},
{
"Method": "SavePriceRecord",
"Parameter": {
"price": {
"value": 1024,
"type": "double"
}
}
}
]
}
準備好 FindMethod 函式來讀取 Json 檔中指定的函式:
public MethodInfo FindMethod(Type SourceClassType, string MethodName)
{
string ServiceName = $"{ MethodName }";
var methods = SourceClassType.GetMethods();
var listMethods = methods.Where(method => method.Name.ToUpper().Equals(ServiceName.ToUpper())).ToList();
if (listMethods.Count() == 1)
{
return listMethods[0];
}
return null;
}
於 Controller 加入執行程式:
public ActionResult Index()
{
LoadJson();
dynamic jsonObj = JsonConvert.DeserializeObject(json);
Type newType = ReflectTool.GetTypeByLoadDLL(jsonObj.DLLPath.ToString(), jsonObj.DLLModule.ToString());
var instance = ReflectTool.ProductInstantByType(newType);
foreach(var service in jsonObj.Services)
{
MethodInfo Info = FindMethod(newType, service.Method.ToString());
var parameters = Info?.GetParameters();
if (parameters != null)
try
{
var arguments = new object[parameters.Length];
if (parameters.Length > 0)
{
for (int i = 0; i < parameters.Length; i++)
arguments[i] = ConvertType(service.Parameter[parameters[i].Name].type,
service.Parameter[parameters[i].Name].value);
}
Info.Invoke(instance, arguments);
}
catch
{
System.Diagnostics.Debug.WriteLine("execute method fail!");
}
}
return View();
}
其執行結果:
(1) 執行 json 檔 指定 ExecServiceSetting 函式
(2) 執行 json 檔 指定 SavePriceRecord 函式
以上為由外部擴充功能,透過 json 檔指定資訊來執行擴充功能的實驗。