最近在看ASP.NET Core MVC的教材,幾乎每章開始都要重復從Empty project開始創建一個ASP.NET Core的項目,然后手動修改project.json,增加經典三目錄(Models,Controllers,Views)之類的,然后接着基於這個基本項目進行介紹某個特定的功能。
這種示例代碼每次都重復創建很沒有技術含量,通常都是復制粘貼,所以考慮把這部分示例代碼做成一個自動化的。之前有看到有ASP.NET Identity的示例的Nuget程序包,就是安裝之后,自動創建了相關的類文件,同時也修改了web.config,最終效果是安裝了package之后,直接能起來。
遵循這個想法,也打算創建一個ASP.NET Core MVC的基本示例Nuget包。於是從新復習了一個創建Nuget包的文檔,發現情況不是那么直接,用之前基於非.NET Core的程序的創建包的方式,行不通。
查看了Nuget提供的文檔說明(https://docs.microsoft.com/zh-cn/nuget/),也沒找到很直接的說明如何創建.NET Core程序包的介紹文檔,反而看到有介紹創建.NET Standard程序包的文檔。這是什么情況,按道理不可能,可能方向不對?直接bing了一下,也沒有找到stackflow上的最佳答案,其實也沒深入去找,我是覺得自己走錯了方向。
於是把介紹創建.NET Standard的文檔(https://docs.microsoft.com/zh-cn/nuget/guides/create-net-standard-packages-vs2015)看了一遍,看到前面的介紹終於明白了,原來是換了個殼,沒有之前那么直接了,必須通過創建.NET Standard包的方式實現對.NET Core程序的支持。
為什么是.NET Standard?.NET Standard定義了支持所有.NET平台的BCL程序集API,理論上說.NET Standard支持下的程序集可以在多個不同的.NET平台運行,比如.NET Framework,.NET Core, Mono等等。而對於不同的.NET平台,對.NET Standard的版本支持也不同,完成的支持列表可參考https://docs.microsoft.com/en-us/dotnet/articles/standard/library的說明,下圖是引用自官網的一個版本支持圖
參考需要支持的.NET平台的版本,可以看到平台支持的最高版本的.NET Standard的版本號,同時也說明支持之前版本的.NET Standard。
說的比較拗口,比如我這里需要支持.NET Core程序,而且是.NET Core 1.0版本,那么這個版本支持的最高.NET Standard版本是1.6,同時也兼容1.6之前的版本。
好了前面介紹了一下背景知識,那么了解完之后我們就很清楚如果要創建支持.NET Core的Nuget包,那么我們需要創建一個支持.NET Standard的Nuget包,並且設置支持的版本即可。
結合Nuget官方的文檔,我們一步步來創建並發布一個Demo版的支持.NET Core 1.0版本的Nuget包。
1 用Visual studio 2015新建一個Class Library Portable項目
項目名稱自定義,通常用於最終Nuget包的名稱
2 點擊確定之后彈出選擇需要的Targets,也就是支持的.NET平台
這里選擇支持.NET Framework和ASP.NET Core
3.點擊OK之后,項目創建完成,然后右鍵點擊解決方案,打開屬性窗口
選擇點擊”Target.NET Platform Standard”,之后會有一個Confirm,當然是選擇“Yes”
然后屬性窗口的Target變成了一個下拉選項,這里我們選擇.NET Standard1.4版本即可(根據版本支持圖,.NET Core 1.0可以支持這個版本)
之后再次Confirm,Yes
3 設置Build,選擇Release,並勾選中XML documentation file,后面需要用到
4 到此項目的屬性設置完成,然后把默認生成的Class1改一下,好歹改成一些有意義的東西,我改成如下內容。
public class Demo { public void Run() { Console.WriteLine($"You're using my demo package at {DateTime.Now.ToString(CultureInfo.InvariantCulture)}"); } }
5 項目代碼已經足夠了,接下來使用Nuget命令行工具,Nuget命令行工具用的是3.5版本,官方有得下載,這里把Nuget.exe文件放到了項目根目錄下。
6 然后CMD到項目所在的目錄,運行nuget spec,創建一個spec文件,這個文件干嘛的不多說了,官方文檔有詳細說明
nuget spec
然后得到一個Shenba.DemoPackage.Core.nuspec文件
7 用文本編輯器,比如notepad++編輯Shenba.DemoPackage.Core.nuspec文件
把各個$符號的變量都改成自己的內容,比如如下內容
<?xml version="1.0"?> <package > <metadata> <id>Shenba.DemoPackage.Core</id> <version>1.0.0</version> <title>Shenba.DemoPackage.Core</title> <authors>shenba</authors> <owners>shenba</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>demo package for dotnet core</description> <releaseNotes>demo package for dotnet core released.</releaseNotes> <copyright>Copyright 2017</copyright> <tags>dotnet core demo package</tags> </metadata> </package>
注意id不要相同,否則后面沒法提交
8 繼續編輯nuspec文件,加入<files>節點(跟metadata一個級別),並設置內容如下
<files> <file src="bin\Release\Shenba.DemoPackage.Core.dll" target="lib\netstandard1.4\Shenba.DemoPackage.Core.dll" /> <file src="bin\Release\Shenba.DemoPackage.Core.xml" target="lib\netstandard1.4\Shenba.DemoPackage.Core.xml" /> </files>
9 在Release配置下,編譯解決方案后,在命令行執行如下命令(還是在項目的根目錄下)
nuget pack Shenba.DemoPackage.Core.nuspec
之后會生成一個Shenba.DemoPackage.Core.1.0.0.nupkg文件,這個就是最終要發布的包文件
實際上這是一個壓縮包(把后綴名改成zip),可以用RAR工具查看里面的文件結構,如下圖
可以看到里面包含了常見的lib目錄,並且打開后是netstandard1.4目錄,然后是具體的程序集文件和XML文檔。
10 接下來就是把這個包發布到nuget.org
發布到nuget.org需要使用自己的賬號發布,如果通過命令行發布還需要生成自己的一個API key,具體可以參考https://docs.microsoft.com/zh-cn/nuget/create-packages/publish-a-package的說明。
這里給出發布的package的命令行,其中XXXX是注冊后得到的API key
nuget push Shenba.DemoPackage.Core.1.0.0.nupkg XXXX –Source nuget.org
11 push之后是不能立即在nuget搜索到的,這跟之前的非.NET Standard的是一樣的,不過可以在自己的Account下看到發布的包
12 在.NET Core項目中使用剛發布的Demo package
這個跟使用普通的.NET Core的Package一樣,修改project.json或者使用界面的package manager引入,比如直接在project.json的dependencies節點加入package的引用
{ "version": "1.0.0-*", "buildOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.1" }, "Shenba.DemoPackage.Core": "1.0.0" }, "frameworks": { "netcoreapp1.0": { "imports": "dnxcore50" } } }
保存之后當然也會自動的restore,然后會顯示在引用中
當然代碼里調用這個package的類也是沒有問題的,調用代碼就不說了,就是個示例而已。
13 在.NET Framework 4.6.1的項目中使用該Demo package
一開始提到這個package是基於.NET Standard1.4版本的,根據版本支持圖,.NET Framework 4.6.1的項目也是可以引用這個包的。
新建一個.NET Framework 4.6.1的控制台項目,package控制台運行
Install-Package Shenba.DemoPackage.Core
同樣也是能正確被引用和調用的,下面是packages.config的內容
<packages> <package id="Shenba.DemoPackage.Core" version="1.0.0" targetFramework="net461" /> </packages>
小結
以上是創建並發布一個可用於.NET Core(當然也可用於.NET Framework)的Nuget包過程,大致流程跟發布普通的Nuget包相同,但需要注意選擇需要支持的.NET Standard的版本。
后續會准備一個更加有意義的.NET Core包,可用於生成ASP.NET MVC Core的學習示例代碼。
(目前針對dotnet core項目的nuget包,還不支持執行包里的代碼模板和識別Content內容,所以暫時無法實現
詳情參考 https://docs.microsoft.com/zh-cn/nuget/create-packages/project-json-impact)
這個Demo的示例代碼路徑
https://github.com/shenba2014/AspDotNetCoreMvcExamples/tree/master/DemoPackageCore