2

結果を処理して返す基づくスクリプトルールエンジンを使用しています。の作成、構成、および解析を何度も繰り返すことを避けるために、の1つのインスタンスを再利用したいと思います。IEnumerable<T>IEnumerable<T>ScriptEngineScriptEngine

これが短いサンプルです(gist.github.comの完全なサンプル):

var engine = new ScriptEngine();

new[]
{
    typeof (Math).Assembly,
    this.GetType().Assembly
}.ToList().ForEach(assembly => engine.AddReference(assembly));

new[]
{
    "System", "System.Math", 
    typeof(Model.ProcessingModel).Namespace
} .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace));

IEnumerable<Model.ProcessingModel> models = new[]
{
    new Model.ProcessingModel { InputA = 10M, InputB = 5M, Factor = 0.050M },
    new Model.ProcessingModel { InputA = 20M, InputB = 2M, Factor = 0.020M },
    new Model.ProcessingModel { InputA = 12M, InputB = 3M, Factor = 0.075M }
};

// no dynamic allowed
// anonymous class are duplicated in assembly
var script =
    @"
    Result = InputA + InputB * Factor;
    Delta = Math.Abs((Result ?? 0M) - InputA);
    Description = ""Some description"";
    var result = new { Σ = Result, Δ = Delta, λ = Description };
    result
    ";

// Here is ArgumentException `Duplicate type name within an assembly`
IEnumerable<dynamic> results =
                models.Select(model => engine.CreateSession(model).Execute(script));

そして、ここにいくつかの問題があります:

  • dynamicはキーワードをサポートしていません
  • スクリプト内で匿名型を使用しているときに、 Duplicate type name within an assemblyがを使用してアセンブリを作成しているときに例外が発生しますSystem.Reflection.Emit

質問

ScriptEngineスクリプトに匿名タイプが含まれている場合に、それを何度も作成して再利用する方法はありますか?

4

1 に答える 1

2

Roslynでバグが発生しています。

スクリプトをループでコンパイルしないことをお勧めします。コードは変更されないため、スクリプトが処理しているデータのみを更新する方がはるかに効率的です。このようなアプローチもバグを回避します。

var model = new Model();
var session = engine.CreateSession(model);
var submission = session.CompileSubmission<dynamic>(script);
foreach (Model data in models)
{
    model.InputA = data.InputA;
    model.InputB = data.InputB;
    model.Factor = data.Factor;

    dynamic result = submission.Execute();
    Console.WriteLine("{0} {1} {2}", result.Σ, result.Δ, result.λ);
}
于 2013-03-19T20:44:24.730 に答える