前幾篇文章說到了 模擬做到 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