Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm working with scripting rules engine based on that will process IEnumerable<T> and returns results as IEnumerable<T>. To avoid creating of ScriptEngine, configuring and parsing again and again, I'd like to reuse one instance of ScriptEngine.

Here is a short sample (full sample at 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));

And here are several issues:

  • does not support dynamic keyword
  • While using anonymous types inside script I get an exception Duplicate type name within an assembly when is creating assembly using System.Reflection.Emit

Question

Is there way to create ScriptEngine and reuse it many times when script contains anonymous type?

share|improve this question

1 Answer

up vote 2 down vote accepted

You're hitting a bug in Roslyn.

I'd recommend not compiling the script in a loop. Since the code doesn't change it is much more efficient to only update the data the script is working with. Such approach also avoids the bug.

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.λ);
}
share|improve this answer
Thx, it works fine. I have updated sample at gist.github.com – Akim Mar 20 at 11:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.