[C#][.NET Core] 設計使用 Jint 反射 dll 執行外掛程式

2022-02-22

前幾篇文章說到了 模擬做到 XMLHttpRequest (XHR) 的效果 還有 試著在 Jint 引入其他的 .js 檔案,模擬類似 require 的效果 

因為 Jint 跟 C# 的程式碼混和執行,這我們之前文章 試著用 C# 透過 Jint 執行 Javascript ,混和執行 ,已經說過了

但是畢竟你能提供的有限,有沒有可能讓有能力的客戶自己撰寫自己要的呢?


後來想一下這需求,其實我只要提供一個 interface 給有能力的客戶,然後我透過反射的方式,也就是客戶只要提供給我 Class Name 

還有他的 dll 也就是我就透過反射就可以呼叫他寫的程式。


1. 制定 一個簡單的  interface ,這裡面我沒啥設計就是一個 CallResult 的 method 可以去呼叫結果,傳入的部分就是 string 

public interface IDPlugin { int Version { get; } string Name { get; } string CallResult(string input); }


2.開一個專案 DPlugin1,做一個名稱為 MD5 的 class  繼承 IDPlugin,這邊我撰寫的是一個 將字串 加入 特殊的 salt 然後轉 MD5

using JintDPlugin; namespace DPlugin1 { public class MD5 : IDPlugin { public int Version { get { return 2022222; } } public string Name { get { return "MD5 Library"; } } public string CallResult(string input) { var x = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] bs = System.Text.Encoding.UTF8.GetBytes(input+","+"當麻的鹽 DONMA's SALT"); bs = x.ComputeHash(bs); var s = new System.Text.StringBuilder(); foreach (byte b in bs) { s.Append(b.ToString("x2").ToLower()); } string password = s.ToString(); return password; } } }


3. 編譯後 拿到一個 DPlugin1.dll  之後 複製到主專案中根目錄下 再來我們看看如何執行 DPlugin1.dll

using System; namespace JintDPlugin { class Program { public class ReflactAgent{ public string GetInfo(string file, string className) { System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + file); foreach (var t in assembly.GetTypes()) { if (t.IsClass && t.Name == className) { var ins = (Activator.CreateInstance(t) as IDPlugin); return ins.Name + "," + ins.Version; } } throw new EntryPointNotFoundException("I cant Find class."); } public string Run(string file,string className,string input) { System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + file); foreach (var t in assembly.GetTypes()) { if (t.IsClass && t.Name == className) { return (Activator.CreateInstance(t) as IDPlugin).CallResult(input); } } throw new EntryPointNotFoundException("I cant Find class."); } } static void Main(string[] args) { var engine = new Jint.Engine(); engine.SetValue("PLUGIN", new ReflactAgent()); var jsCode = @" function Main(){ return PLUGIN.Run('DPlugin1.dll','MD5','當麻許測試'); } function LibInfo(){ return PLUGIN.GetInfo('DPlugin1.dll','MD5'); } "; engine.Execute(jsCode); var info = engine.Execute("LibInfo()").GetCompletionValue(); Console.WriteLine(info); //MD5 Library,2022222 var result = engine.Execute("Main()").GetCompletionValue(); Console.WriteLine(result); //c5222b26b6f1a1f3b7e1b5a847b133fa } } }


其實觀念懂了不難,但是可以做到很多驚人的效果,方便佈局規劃妳的系統

完整程式碼可以到這下載:

https://github.com/donma/JintPluginSample


當麻許的碎念筆記 2014 | Donma Hsu Design.