以前在外商工作,系統採用一個很特別的設計,就是商業邏輯放在XML檔,裡面可以放簡單的判斷式。但因為得自己寫parser,所以能做的事有限,且當時沒找到適合的script工具。而現在可以在.NET程式中執行外部的C#程式碼,也就是把C#程式碼當script用。

例如可以把1+1當成外部script,執行後可直接得到結果。

要做到這種效果,可藉由Microsoft.CodeAnalysis.CSharp.Scripting元件,從nuget上安裝即可,以下是簡單的範例:

var imports = new List<string>
{
    "System",
    "System.Math",
    "System.Linq",
    "System.Text",
    "System.Text.RegularExpressions",
    "System.Collections",
    "System.Collections.Generic",
    "System.Dynamic",
};
var references = new List<Assembly>
{
    typeof(Match).Assembly,
    typeof(Regex).Assembly,
    typeof(System.Linq.EnumerableQuery).Assembly,
    typeof(System.Dynamic.BinaryOperationBinder).Assembly,
    typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly
};
var options = ScriptOptions.Default
                           .WithReferences(references)
                           .WithImports(imports)
                           .WithAllowUnsafe(false);

設定之後,就可執行程式碼:

var r = await CSharpScript.EvaluateAsync(exp, options);
Person p = new Person { Age = 1, Name = "Peter" };
var q = await CSharpScript.RunAsync(@"Age+3", globals: p);
Console.WriteLine(r);
Console.WriteLine(q.ReturnValue);

也可執行dynamic語法:

InputData data = new InputData();
data.DynObj.Foo = 1;//DynObj為dynamic物件
var f = await CSharpScript.RunAsync(@"DynObj.Foo+1", options, globals: data);
Console.WriteLine(f.ReturnValue);

參考資料