WINDOWS 10 2015 年特別版
# Visual Studio 工具 - NuGet 功能增強了 Windows 10 的開發功能
作者?[Jeff Fitz](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Jeff+Fitz)?| Windows 2015
現在 NuGet 團隊提供了幾款全新工具。它與 Microsoft 的一些團隊合作推出了新版本的 NuGet 客戶端,以支持通用 Windows 平臺 (UWP) 和新的可移植類庫 (PCL)。新的 NuGet 工具可通過“工具 | 擴展和更新 | Visual Studio 2015 中的更新”獲取,還可以從 NuGet 分布站點獲取,網址為:[bit.ly/1MgNt2J](http://bit.ly/1MgNt2J)。NuGet 還發布了新版本的 NuGet 命令行工具,您可以從 dist.nuget.org 上的相同位置下載它。本文將回顧這些新功能和 Windows 開發者向 Windows 10 項目添加 NuGet 支持需要遵循的進程。
## Project.Json
從 ASP.NET 5 開始,NuGet 引入了 project.json 文件支持,以便使用您會立即依賴的程序包的明確定義來描述項目依賴項。在 ASP.NET 5 中,這是定義項目配置的唯一文件。但是借助 NuGet 3.1,您可以在通用 Windows 項目和現代 PCL(面向 DNX、UWP 和 Microsoft .NET Framework 4.6)中使用此文件來定義程序包引用。這種方法的好處就是 Visual Studio 中的“管理程序包”對話框將基于您所開發的項目類型,適當維護您的 packages.config 或 project.json 文件。
這一轉變從 packages.config 模型開始,還允許您“重啟”項目中的引用,并使用 NuGet 的新的可傳遞依賴項功能。開發者和程序包作者向 NuGet 團隊報告,當他們將程序包添加到項目時,他們的 packages.config 文件會與其依賴程序包中的依賴項混淆。
例如,NHibernate 是依賴于 Iesi.Collections 程序包的程序包。在 packages.config 中有兩個引用:NHibernate 和 Iesi.Collections。在更新 NHibernate 時,會遇到一個問題“我是否也要更新 Iesi.Collections?” 同樣存在與此相反的問題。如果有適用于 Iesi.Collections 的更新,我是否需要更新 NHibernate 來支持 Iesi.Collections 中的新功能? 開發者可能會陷入對程序包引用所帶來的項目程序包依賴項進行管理的令人厭惡的循環。
NuGet 的可傳遞依賴項功能簡化了這一決定,通過程序包定義文件(nuspec 文檔)中語義版本的改進支持更新程序包引用。開發者指定了其程序包支持的依賴項版本范圍。當 NuGet 安裝客戶端時,這些依賴項會對 packages.config 文件中的指定版本添加硬引用,這些引用的程序包看上去就像您添加到項目中的任何其他程序包引用。您可以在圖 1?中看到這一問題的極好示例。
圖 1 ASP.NET MVC packages.config 文件的內容
~~~
<?xml version="1.0" encoding="utf-8"?>
<packages>
? <package id="Antlr" version="3.4.1.9004" targetFramework="net46" />
? <package id="bootstrap" version="3.0.0" targetFramework="net46" />
? <package id="EntityFramework" version="6.1.3" targetFramework="net46" />
? <package id="jQuery" version="1.10.2" targetFramework="net46" />
? <package id="jQuery.Validation" version="1.11.1" targetFramework="net46" />
? <package id="KendoUICore" version="2015.2.624" targetFramework="net46" />
? <package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net46" />
? <package id="Microsoft.AspNet.Identity.EntityFramework"
??? version="2.2.1" targetFramework="net46" />
? <package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net46" />
? <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net46" />
? <package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net46" />
? <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net46" />
? <package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net46" />
? <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform"
??? version="1.0.0" targetFramework="net46" />
? <package id="Microsoft.jQuery.Unobtrusive.Validation"
??? version="3.2.3" targetFramework="net46" />
? <package id="Microsoft.Net.Compilers"
??? version="1.0.0" targetFramework="net46" developmentDependency="true" />
? <package id="Microsoft.Owin" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.Facebook" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.Google" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.MicrosoftAccount"
??? version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Owin.Security.Twitter" version="3.0.1" targetFramework="net46" />
? <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
? <package id="Modernizr" version="2.6.2" targetFramework="net46" />
? <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net46" />
? <package id="Owin" version="1.0" targetFramework="net46" />
? <package id="Respond" version="1.2.0" targetFramework="net46" />
? <package id="WebGrease" version="1.5.2" targetFramework="net46" />
</packages>
~~~
在我將這些內容添加到項目中時,我實際上只需要 Microsoft.AspNet.Mvc、Microsoft.AspNet.Identity.EntityFramework、Newtonsoft.Json 和 Microsoft.Owin.Security.MicrosoftAccount。這四個程序包所引用的其他項目都只是干擾,現在我有特定版本的硬引用。通過可傳遞依賴項功能,不再需要其他這些程序包的版本。我只需管理我真正要在項目中使用的四個庫。
NuGet 客戶端會在后臺為您解決和管理其他這些程序包,并將這些引用保持在項目中正在使用的程序包所聲明的依賴版本約束范圍內。這會極大地簡化項目引用體驗。
## 常見的本地程序包緩存
開發者通常有自己傾向使用的一些程序包和工具。在您明顯已經在某個項目中擁有這些程序包和工具并想在另一個項目中使用時,為什么需要在單個工作站上多次下載并安裝它們? 通過 project.json 托管的項目,NuGet 下載這些程序包的副本并將其存儲在位于 %userprofile%\.nuget\packages 文件夾的全局程序包文件夾中。這會減少在工作站上使用磁盤空間。還能避免額外調用,這些調用從 NuGet.org 提取程序包來獲取您已經擁有的項目。
Project.json 和常見的本地程序包緩存支持可供包含 NuGet 3.0 的 ASP.NET 5 以及其他始于 NuGet 3.1 的項目類型使用。
## 棄用的功能
從 NuGet 3.1 開始,在使用 project.json 時,棄用對執行 install.ps1/-uninstall.ps1 腳本和在 /content 程序包文件夾中傳遞元素的支持。使用這些元素安裝程序包既不會執行 install.ps1 文件,也不會將內容復制到您的項目中。但是,在仍使用 packages.config 文件的項目中,仍然支持執行當前行為。出現這一情況有幾個原因:
* 隨著可傳遞程序包還原,無法可靠地選取要卸載和安裝的程序包。
* 在將內容復制到用戶項目,且程序包進行了更新時,會存在您無法可靠運行的隱式卸載過程。
* NuGet 需要完全支持 Visual Studio 之外的開發。隨著轉向支持完全跨平臺 .NET 開發體驗,Windows Powershell 在其他環境中不可用。更多的開發者還致力于開發 Visual Studio 之外的 .NET 代碼,他們需要支持。
* 其他程序包管理器提供了管理和傳遞內容的卓越體驗。NuGet 可以作為 .NET Framework 的程序包管理器良好地工作,因此,鼓勵繼續使用。
* 不再支持“任何”框架。您無法再將文件直接放置于版本的根和庫文件夾中,并將它們傳送給項目。聲明您的文件所支持的框架是非常重要的,這樣,NuGet 才能了解解析這些引用的優先級順序。
* 不再支持解決方案包。這些程序包不能修改任何指定項目的功能,通常用于提供跨項目重復使用的共享資源。借助新共享的程序包文件夾,這些資源可能已經位于另一個項目的磁盤上。
## 新目標框架
NuGet 新版本的另一方面是支持新開發框架以及跨操作系統和體系結構的改進的本機程序包支持。NuGet 進一步探索了托管 .NET Framework 模型之外的環境,以支持更多的生態系統,使您可以將庫部署到以前無法訪問的環境。
目標框架名字對象 (TFM) 是一種簡寫形式,用于創建程序包來聲明二進制支持的框架以及每個框架需要的依賴項。您將在使用此表示法的程序包庫和 ref 文件夾中找到文件夾的名稱。程序包的 nuspec 依賴項元素中還有一些元素,這些元素使用一個 TFM 值聲明目標框架屬性來指示 NuGet 客戶端將相應的庫傳遞給使用項目。
下列 TFM 仍可用,引入的新 TFM 如圖 2?所示。
圖 2 NuGet 3.x 支持的目標框架
| 說明 | 基礎代碼 | 可用版本 |
|---|---|---|
| 托管框架應用程序(Windows 窗體、控制臺應用程序、Windows Presentation Foundation 和 ASP.NET) | net | net11、net20、net35、net35-client、net35-full、net4、net40、net40-client、net40-full、net403、net45、net451、net452 和 net46 |
| ASP.NET 5 | dnxcore | dnxcore50 |
| Windows 應用商店 | netcore | win8 = netcore45、win81 = netcore451 和 uap10.0 |
| Windows Phone(appx 模型) | wpa | wpa81 |
| Windows Phone (Silverlight) | wp | wp7 = sl3-wp、wp71 = sl4-wp71、sl4-wp、wp8 = wp8- 和 wp81 |
| Silverlight | sl | sl2、sl3 = sl30、sl4 = sl40 和 sl5 = sl50 |
| Xamarin | ? | mono、MonoMac、Xamarin.Mac、MonoAndroid10、MonoTouch10 和 Xamarin.iOS10 |
| Compact Framework | net-cf | net20-cf、net35-cf = cf35 和 net40-cf |
| Micro Framework | netmf | netmf41、netmf42 和 netmf43 |
所列出的帶有等于 (=) 符號的項是 NuGet 支持的同義詞。針對許多不同的框架有許多支持,但這可能會造成混淆。您是否需要為托管框架包中的微框架提供支持? 您需要獲得多少 Silverlight 支持? 您需要回答這些問題,以便最符合使用者的需求。
您會發現表中沒有支持 PCL 的顯式調用。盡管 NuGet 支持這些框架的組合,但它希望您擁有適用于現代 PCL 的更加向前兼容的名字對象。這會在您構造程序包和定義支持框架時提供更多的靈活性。NuGet 3.1 引入了適用于現代 PCL 的 dotnet 目標名字對象。
## Dotnet 目標名字對象
在 NuGet 的早期版本中,您可以指定帶有 PCL 的框架,該框架作為后接加號符號的 TFM 縮寫的集合。您可能會使用類似“portable-net45+win8+wpa81+wp8”作為文件夾名稱的結尾。 這可能會造成混淆,給使用者帶來不兼容的問題。為了使 PCL 和跨平臺開發體驗更加簡單,NuGet 引入了 dotnet 名字對象。
此名字對象不會直接與任何指定版本或框架功能綁定。這是一個間接的引用,告訴 NuGet“如果它支持您擁有的框架和運行時功能的話,這是您應該使用的應用。” 然后 NuGet 客戶端研究該引用以確定其支持的功能和框架。這一進程會持續,直到 NuGet 客戶端解析 dotnet 引用支持的確切功能。然后,只有在引用匹配項目的功能和需求的情況下,客戶端才會應用該引用。您可以通過 .NET Framework 4.5 以及后續派生的 Framework 版本(包括 Xamarin Android 和 Xamarin iOS)來引用 dotnet 名字對象。
這并不意味著您只需構建 PCL,并將其與聲明的 dotnet 依賴項捆綁在一起,就完成操作了。如果您想要使用舊版本的 Visual Studio 和通過傳統可移植類庫構建的 NuGet 客戶端來支持項目,則應創建一個引用,并將其放置于完整 PCL 目標框架名字對象中。
在將程序包安裝到與 dotnet 名字對象(.NET Framework 4.6、UWP 或 ASP.NET 5)完全兼容的項目類型時,最后會搜尋 dotnet 名字對象。在嘗試查找與項目的框架或不太具體的框架相匹配的引用后,將會引發上述操作。該層次結構如圖 3?所示。

圖 3 框架層次結構,檢查其中是否存在對通用 Windows 平臺項目的引用
如果您的項目是使用僅針對這些框架中的任一個框架的 project.json 的現代 PCL,則會首先分析 dotnet 名字對象。后跟一個標準的 PCL 解決策略,如圖 4?所示。

圖 4 框架層次結構,檢查其中是否存在對現代可移植類庫項目的引用
## NuGet 命令行
現在 NuGet 類似于命令的可執行文件 nuget.exe 可用于支持將程序包安裝、更新和還原到包含 packages.config 文件或 project.json 文件的項目。pack 命令可以繼續使用磁盤上的 nuspec 文件和 packages.config 文件。它并沒有更新為基于 project.json 文件生成 nuspec 文件。要解決此問題,您需要針對任何通過 project.json 程序包引用構造的新程序包內容構建您自己的 nuspec 文件。未來版本中將包含解決此問題的更新。
此版本的命令行可執行文件還支持 NuGet.org v3 終結點。此 nuget.org 源的新版本提供更快的交互,同時也是更加可靠的服務。通過內置的冗余和內容傳送網絡可以幫助快速傳遞程序包。從以下網址下載更新 NuGet.exe 的副本:[bit.ly/1UV0kcU](http://bit.ly/1UV0kcU)。
如果您在升級 NuGet 擴展后安裝了 Windows 10 SDK/Windows 10 工具,則安裝程序會將此擴展降級為版本 3.1。您需要重新將其至少更新為 3.1.1 版本。在此“擴展和更新”對話框中顯示的版本是 3.1.60724.766。Windows PowerShell 控制臺是 3.1.1.0。
## 總結
現已提供支持 Windows 10 UWP 應用程序開發和 PCL 項目的功能。這些更改是廣泛使用程序包管理器和 .NET Framework 的第一步。Microsoft 持續改進 .NET 開發體驗,并專注于提供程序包管理器,以支持所有 .NET 開發者在任何平臺上構建任何類型的項目。
* * *
Jeffrey T. Fritz?*是就職于 Microsoft NuGet 團隊的高級項目經理。他喜歡長時間地在海灘上散步,并處理在云中縮放的 Web 應用程序。您可以通過?[jefritz@microsoft.com](mailto:jefritz@microsoft.com)?與他聯系。*
- 介紹
- Microsoft .NET - .NET 和通用 Windows 平臺開發
- 圖形和動畫 - Windows 組合支持 10 倍縮放
- 應用生命周期 - 通過后臺任務和擴展執行使應用處于活動狀態
- 通知 - Windows 10 中的自適應和交互式通知
- 應用集成 - 在 Windows 10 上鏈接和集成應用
- Visual Studio 工具 - NuGet 功能增強了 Windows 10 的開發功能
- UI 設計 - 通用 Windows 應用的響應式設計
- UI 設計 - 適用于 Windows 10 的自適應應用
- 數字墨跡 - Windows 10 中的墨跡交互
- 游戲開發 - 使用 Unity 為通用 Windows 平臺編寫游戲
- 結束語 - 歡迎使用 Windows 10 應用開發
- 編者寄語 - 從 3.0 開始的發展之路