Compiler Roslyn in. NET core and. NET 4.6 in C # 6/7 an important feature is the "Compiler as a service", which simply means that the compiler is open to services that can be called in code, usually in the workflow engine or the rule engine To have a function is to evaluate an expression, I usually use the ANTLR [ANTLR ("Another language recognition tool" abbreviation) before Roslyn, which is a library originally written in Java that can build complex parser code based on special syntax (grammar). It is like a regular expression for the enhanced version of Language parsing. You can write a grammar rule for a language, ANTLR will generate code for you], and based on ANTLR there is a lightweight C # compiler service expression Evaluator.
To use Roslyn to execute C # scripts in your own code, start with the following steps.
1. Install Microsoft.CodeAnalysis.CSharp.Scripting through NuGet
2. Add a reference to the following namespace in your code.
Using Microsoft.CodeAnalysis.CSharp.Scripting;
Using Microsoft.CodeAnalysis.Scripting;
The classic HelloWorld
Let's start with the classic Hello world to get started on how to execute a script.
static void Main (string[] args)
{
var options =
Scriptoptions.default
. Addreferences ("System.Runtime, version=4.1.0.0, Culture=neutral, publickeytoken=b03f5f7f11d50a3a");
var bar = new Bar () {StaffID = 5686, Unitid = 2, age = 15};
Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync ("System.Console.WriteLine (\" Hello world\ ");", Options);
}
As you can see from the code above, executing a script is relatively straightforward, and you can execute your own script through the Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync () function. It is also easy if we want to get the return value of the script.
var scriptstate = csharpscript.runasync<int> ("3+2*5", Scriptoptions.default);
Console.WriteLine (scriptstate);
Executing scripts in a session
Many times, we cannot execute all the scripts at once, but instead enter a sentence as in the shell. If we execute the following code
Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync ("var i = 3;");
var result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync ("I * 2");
What we get is not the result we want 6, but an exception:
The reason for this is that the Csharpscript.runasync function is executed each time in a separate context and is not associated with the preceding statement. If we want to create a script in the Csharpscript.create () function, the function ContinueWith make up a complete script to run. The correct way is as follows:
var s0 = csharpscript.create ("int x = 1;");
var S1 = S0. ContinueWith ("int y = 2;");
var s2 = S1. Continuewith<int> ("x + y");
Console.WriteLine (S2. RunAsync (). Result.returnvalue);
Sharing data in scripts and programs
When we execute the script, in addition to get the output of the script, many times we need to set the script input, there are many ways to set the input. The most straightforward way to stitch scripts but the efficiency and maintainability of doing so is very poor. Also can through the traditional IPC communication mechanism-file, socket, and so on, this way is more troublesome, and for complex objects, but also involves serialization, is very inconvenient.
Roslyn provides a simpler and more efficient workaround: Passing in a host object in a session, the script in the session can also access the member variables of the host object.
Namespace Roslyncosonle
{
class program
{
static void Main (string[] args)
{
var options =
Scriptoptions.default
. Addreferences ("System.Runtime, version=4.1.0.0, Culture=neutral, publickeytoken=b03f5f7f11d50a3a");
var s0 = csharpscript.create ("int x = 1;");
var S1 = S0. ContinueWith ("int y = 2;");
var s2 = S1. Continuewith<int> ("x + y");
Console.WriteLine (S2. RunAsync (). Result.returnvalue);
var bar = new Bar () {StaffID = 5686, Unitid = 2, age = 15};
Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync ("System.Console.WriteLine (staffid==5686 & & unitid==2) | | (Unitid = = 3| | Age >10)); ", options, bar);
}
}
public class Bar
{
public string Foo = "Hello world!";
public int StaffID {get; set;}
public int Unitid {get; set;}
public int Age {get; set;}
}
The input passed to the object bar is passed to the expression, and then the expression evaluates the result, and this is the expression that we want in the workflow engine.
Using the Roslyn compiler service