. net core -- compiling C# code with roslyn

Posted by John_S on Tue, 18 Jan 2022 15:15:41 +0100

catalogue

Introduction to Rosyln

Compile c# text as dll in real time

1. Add the PreserveCompilationContext configuration

2. Reference package

3. Get the compilation reference dll by using {DependencyContext}

Complete example

Reference test library

summary

Footnotes

 

Introduction to Rosyln

Rosyln1{yes NET Core and NET 4.6 +, which is also used by IDE Visual Studio to compile code. Based on the idea that the compiler is also a service, Microsoft developers separate it and maintain it open source. See footnote 2 for the open source address.
In the workflow engine or rule engine, it is sometimes necessary to calculate expressions. In the past, we usually used Antlr 3 to build complex parser code according to special syntax (grammar). It's like an enhanced regular expression for language parsing. Of course, you can also use the popular interpretive language engine to do this. You can refer to my previous article, an introduction to Javascript engine.
There is also a similar C# compiler scripting engine C# Scripting API 4 under Rosyln to complete the following expression evaluation.
Installation package * Microsoft CodeAnalysis. CSharp. Scripting*

int result = await CSharpScript.EvaluateAsync<int>("1 + 2");

Compile c# text as dll in real time

Latest package Microsoft CodeAnalysis. CSharp has been supported net core, so net core has no problem compiling c# strings. Follow the steps below:

1. Add the PreserveCompilationContext configuration

Edit your csproj project file and add the following configuration

<PropertyGroup>
  <PreserveCompilationContext>true</PreserveCompilationContext>
 </PropertyGroup>

2. Reference package

Edit your csproj project file and add the following configuration

 <ItemGroup>
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.11.0-beta1-final" />
    <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
  </ItemGroup>

3. Get the compilation reference dll by using {DependencyContext}

MetadataReference[] _ref = 
    DependencyContext.Default.CompileLibraries
    .First(cl => cl.Name == "Microsoft.NETCore.App")
    .ResolveReferencePaths()
    .Select(asm => MetadataReference.CreateFromFile(asm))
    .ToArray();

Complete example

MetadataReference[] _ref =
             DependencyContext.Default.CompileLibraries
                  .First(cl => cl.Name == "Microsoft.NETCore.App")
                  .ResolveReferencePaths()
                  .Select(asm => MetadataReference.CreateFromFile(asm))
                  .ToArray();         
          string testClass = @"using System; 
              namespace test{
               public class tes
               {
                 public string unescape(string Text)
                    { 
                      return Uri.UnescapeDataString(Text);
                    } 
               }
              }";         
         
          var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
              .WithOptions(new CSharpCompilationOptions(
                  Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary,
                  usings: null,
                  optimizationLevel: OptimizationLevel.Debug, // TODO
                  checkOverflow: false,                       // TODO
                  allowUnsafe: true,                          // TODO
                  platform: Platform.AnyCpu,
                  warningLevel: 4,
                  xmlReferenceResolver: null // don't support XML file references in interactive (permissions & doc comment includes)
                  ))
              .AddReferences(_ref )
              )
              .AddSyntaxTrees(CSharpSyntaxTree.ParseText(testClass));
          var eResult = compilation.Emit("test.dll");

Reference test library

Follow the steps of the above example to successfully generate test DLL file, I reference and test whether it is executable.

var t = new test.tes();
var txt = t.unescape("abcdefg");

Everything is OK, Congratulations! You've done it perfectly net core c#.

summary

The difficulty lies in the introduction of DependencyContext. Many people are stuck in this step because net target will be selected by default when compiling net framework library, then your dll can be generated, but it can't be introduced into net core project!

Footnotes

  1. https://github.com/dotnet/roslyn/wiki ↩︎

  2. https://github.com/dotnet/roslyn ↩︎

  3. https://www.antlr.org/download.html ↩︎

  4. https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples ↩︎

Topics: ASP.NET .NET