dotnet-exec 小工具
dotnet-exec?小工具
Intro
在之前的文章中很多會有一些示例代碼,這些代碼一般都是一些很小的示例,尤其是介紹一些新特性的示例,基本上不會引用其他包,只有 SDK 就可以執(zhí)行,對于這些示例,一般會每個實(shí)例單獨(dú)一個文件,示例程序的入口文件是 MainTest 方法,都用 Main 會造成沖突,所以用了另外一個名字,而 Program 的 Main 方法里或者頂級程序語句中調(diào)用對應(yīng)示例的 MainTest,這樣的話每當(dāng)我想只執(zhí)行每一個示例的時候我就需要修改 Program 中的方法調(diào)用

于是就想著寫一個小工具,用來直接調(diào)用對應(yīng)的示例,這樣既不破壞原來 dotnet run 執(zhí)行運(yùn)行的效果,又可以直接執(zhí)行某一個示例,今天開源的這個小工具 dotnet-exec 就是解決這個小問題的,下面來看一下如何使用以及如何實(shí)現(xiàn)的吧
GetStarted
首先需要安裝 dotnet tool,dotnet tool 基于 .NET 6/7,需要安裝 .NET 6 或者 .NET 7 SDK,SDK 安裝之后
執(zhí)行下面的命令即可安裝
dotnet?tool?install?-g?dotnet-execute
對應(yīng)的命令是 dotnet-exec,可以使用 dotnet-exec -h 來看支持的選項

目前主要用到的 Options:
--entry指定程序的入口,默認(rèn)值是按我自己的習(xí)慣用的MainTest,可以根據(jù)需要自定義,如果有Main方法會優(yōu)先使用Main方法--lang-version指定 C# 語言版本,默認(rèn)使用Default等同于Latest,如果需要使用預(yù)覽版特性需要指定為Preview--args/--arguments指定用戶需要傳入的參數(shù),等同于Main方法的args參數(shù)-c/--configuration指定編譯的優(yōu)化級別,默認(rèn)是 Debug,不進(jìn)行優(yōu)化,可以指定為Release
Sample
百聞不如一見,來看幾個使用的示例吧:
這里是 C# 10 中的一個常量插值字符串的示例,從下圖中可以看到代碼里沒有定義 Main 方法,定義了一個 MainTest 的靜態(tài)方法,我們執(zhí)行 dotnet-exec .\ConstantInterpolatedStringSample.cs 可以看到,執(zhí)行了 MainTest 方法中的邏輯并且,輸出了期望的結(jié)果

這里是前段時間寫的一個 C# 11 的一個新特性—— RawStringLiteral

我們可以通過 dotnet-exec .\RawStringLiteral.cs --lang-version Preview 來執(zhí)行這個示例,這里我們指定了 --lang-version 為 Preview 以啟用還在 Preview 的語言特性

針對原有的 Main 方法和頂級程序語句也是支持的,我們來看幾個示例


Implement
它的實(shí)現(xiàn)原理其實(shí)比較簡單,利用 Roslyn 去編譯這個文件,增加了 Global using 的支持,并且會加上默認(rèn)的 Global using,這樣代碼里可以簡單一些,現(xiàn)在寫的很多示例會啟用隱式命名空間引用,這樣會方便很多
首先會嘗試編譯為一個 Console 應(yīng)用,頂級語句這種語法只支持 Console 應(yīng)用,這樣如果是頂級語句或者包含 Main 方法就和 dotnet run 的運(yùn)行效果是一樣的,如果沒有 Main 方法,編譯會報一個找不到 Main 方法的錯誤,然后會嘗試編譯為一個 dll 通過反射的方式調(diào)用自定義的入口,更多細(xì)節(jié)可以參考源碼:https://github.com/WeihanLi/dotnet-exec/blob/1c83e366c81ab7a51e0995ed0f2a07845b668b89/src/dotnet-exec/CodeCompiler.cs#L38
More
目前只是做了比較簡單處理,只編譯了單個文件,而且沒有檢測項目中的包引用,如果有引用別的項目和文件,現(xiàn)在是不能處理的,后面可以解析文件所在的項目文件中的包引用依賴,編譯整個項目,但是這樣相對來說會復(fù)雜一些,實(shí)現(xiàn)起來可能不會走現(xiàn)在的方式了,后面有需求的話再說吧,暫時基本可以滿足需要
如果你也有類似的需求,可以試一下看能否滿足你的需要
References
https://github.com/WeihanLi/dotnet-exec https://www.nuget.org/packages/dotnet-execute/
