.net core ——利用 roslyn 编译C#代码
Rosyln介紹
Rosyln1?是 .NET Core和 .NET 4.6+ 中 的C# 、VB的編譯器,宇宙最強IDE Visual Studio 也是使用其來編譯代碼的, 基于編譯器也是服務的理念,微軟開發(fā)者把其獨立出來,并開源維護,開源地址參見注腳2。
在工作流引擎 或是規(guī)則引擎中有時候都需要一項功能是計算表達式, 以前我們通常借助于Antlr?3?,根據(jù)特殊的語法(文法)來構建復雜的解析器代碼。它就像是一個用于語言解析的加強版的正則表達式。當然你也可以采用目前流行的解釋型語言引擎來完成此事,可以參考我之前的文章,有一篇有關Javascript引擎的介紹。
Rosyln 下也有一個類似的C#編譯器腳本引擎 C# Scripting API?4?,來完成 類似下面的表達式評估。
安裝包 * Microsoft.CodeAnalysis.CSharp.Scripting*
實時編譯c#文本為dll
最新的包 Microsoft.CodeAnalysis.CSharp 已經(jīng)支持 .net core 了,因此 .net core 下編譯c#字符串已經(jīng)沒有任何問題了。按照下列步驟進行:
1、增加PreserveCompilationContext配置
編輯你的csproj項目文件,增加如下配置
<PropertyGroup><PreserveCompilationContext>true</PreserveCompilationContext></PropertyGroup>2、引用包
編輯你的csproj項目文件,增加如下配置
<ItemGroup><PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.11.0-beta1-final" /><PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" /></ItemGroup>3、利用?DependencyContext?獲取編譯引用dll
MetadataReference[] _ref = DependencyContext.Default.CompileLibraries.First(cl => cl.Name == "Microsoft.NETCore.App").ResolveReferencePaths().Select(asm => MetadataReference.CreateFromFile(asm)).ToArray();完整例子
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, // TODOcheckOverflow: false, // TODOallowUnsafe: true, // TODOplatform: 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");引用test庫
按照上述例子的步驟進行操作,成功生成test.dll文件,我引用并測試它是否可執(zhí)行。
var t = new test.tes(); var txt = t.unescape("abcdefg");一切OK,恭喜!你已經(jīng)完美搞定.net core 下的動態(tài)編譯c#。
總結
難點在于DependencyContext的引入,很多人都是卡在這一步,因為.net 目標編譯時默認會選用 .net framework庫,那么你的dll可以生成,但是沒法引入到 .net core 項目中來!
注腳
https://github.com/dotnet/roslyn/wiki???
https://github.com/dotnet/roslyn???
https://www.antlr.org/download.html???
https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples???
總結
以上是生活随笔為你收集整理的.net core ——利用 roslyn 编译C#代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NET问答: 如何使用 C# 直接从 J
- 下一篇: .NET Core with 微服务 -