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