日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

.net core ——利用 roslyn 编译C#代码

發(fā)布時(shí)間:2023/12/4 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net core ——利用 roslyn 编译C#代码 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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*

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

實(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。