NET Platform Standard
相關博文:ASP.NET 5 Target framework dnx451 and dnxcore50
.NET Platform Standard:https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md
.NET Platform Standard 是什么?直譯過來就是 .NET 平台規范或標准,它的目的就是使 .NET 各個平台之間更加統一和規范,在之前的 .NET Core RC2 發布文章中提到了 .NET Standard Library,它其實就是 .NET Platform Standard 的體現之一,.NET Standard Library 現在有一個對應程序包NETStandard.Library,它的作用是兼容各個 .NET Platform,這個后面有進行說明,現在只是一個臨時方案,以后微軟慢慢會把相關的程序包(比如基礎類庫等),按照 .NET Standard Library 的標准進行開發和發布。
.NET Platform Standard 列表:
| Target Platform Name | Alias | |||||||
|---|---|---|---|---|---|---|---|---|
| .NET Platform Standard | netstandard | 1.0 | 1.1 | 1.2 | 1.3 | 1.4 | 1.5 | 1.6 |
| .NET Core | netcoreapp | → | → | → | → | → | → | 1.0 |
| .NET Framework | net | → | → | → | → | → | → | 4.6.3 |
| → | → | → | → | → | 4.6.2 | |||
| → | → | → | → | 4.6.1 | ||||
| → | → | → | 4.6 | |||||
| → | → | 4.5.2 | ||||||
| → | → | 4.5.1 | ||||||
| → | 4.5 | |||||||
| Universal Windows Platform | uap | → | → | → | → | 10.0 | ||
| Windows | win | → | → | 8.1 | ||||
| → | 8.0 | |||||||
| Windows Phone | wpa | → | → | 8.1 | ||||
| Windows Phone Silverlight | wp | 8.1 | ||||||
| 8.0 | ||||||||
| Mono/Xamarin Platforms | → | → | → | → | → | → | * | |
| Mono | → | → | * |
上面這些都是概念,我們在 ASP.NET Core 1.0 RC2 項目開發中,如何應用和體現呢?其實就是我們在project.json中配置的frameworks節點,我們先看一段配置(來自 Microsoft.EntityFrameworkCore/project.json):
"frameworks": { "net451": { "frameworkAssemblies": { "System.ComponentModel.DataAnnotations": "", "System.Runtime": { "type": "build" } } }, "netstandard1.3": { "imports": [ "portable-net452+win81" ], "dependencies": { "System.Collections.Concurrent": "4.0.12-*", "System.ComponentModel.Annotations": "4.1.0-*", "System.Linq.Queryable": "4.0.1-*", "System.ObjectModel": "4.0.12-*", "System.Reflection.Extensions": "4.0.1-*", "System.Reflection.TypeExtensions": "4.1.0-*" } }, "netcore50": { "dependencies": { "Microsoft.NETCore.Platforms": { "type": "build", "version": "1.0.1-*" }, "System.Collections.Concurrent": "4.0.10", "System.ComponentModel.Annotations": "4.0.10", "System.Linq.Queryable": "4.0.0", "System.ObjectModel": "4.0.10", "System.Reflection.Extensions": "4.0.0", "System.Reflection.TypeExtensions": "4.0.0", "System.Runtime": { "type": "build", "version": "4.0.20" }, "System.Dynamic.Runtime": { "type": "build", "version": "4.0.10" }, "System.Runtime.WindowsRuntime": { "type": "build", "version": "4.0.10" }, "System.Runtime.Extensions": { "type": "build", "version": "4.0.10" } } } }
可以看到frameworks配置了net451、netstandard1.3和netcore50,這些是什么意思?從上面的 .NET Platform Standard 列表中,我們可以得到一些信息,但還是有些不太明白,我們看一下相關解釋(來自 Project.json definition dnx451 vs .dotnet (4.51)):
dnxcore50: DNX SDK running on CoreCLR/CoreFx (deprecated, usenetcoreapp1.0instead).dnx451: DNX SDK running on .Net 4.5.1 (Desktop CLR / Full BCL and FCL) (deprecated, usenet451instead).net46: .Net Framework 4.6 SDK running on Desktop CLR / Full BCL and FCL.uap10.0: UWP Windows 10 SDK running on .Net Native/CoreFx.netcoreapp1.0: .NET Core 1.0 SDK running on CoreCLR/CoreFx.netstandard1.5: (RC2,dotnetbefore) any pure IL code which declares its dependencies (System.Runtime (based) libraries instead of a PCL contracts). Framework dependencies are available for .Net 4.5.x onwards, .NET Core or UWP (System.Runtime based library set in different versions). As with RC2dotnetis deprecated, usenetstandardinstead.
先看dnxcore50的解釋,DNX SDK 是什么?它其實是一種命令或工具,指向你的程序集使用的哪種目標環境,CoreCLR/CoreFx 就是說,程序集跑在 CoreCLR/CoreFx 上,dnxcore50現在已經被棄用了,被 netcoreapp1.0所替代,netstandard1.5是一種新的平台規范,使用它必須引用NETStandard.Library程序包,否則System所有相關命名空間都找不到。
簡單來說,frameworks所配置的就是你程序集的運行環境或平台,如果配置了多個,就表示程序集可以跑在多個平台上,比如,上面Microsoft.EntityFrameworkCore配置了net451、netstandard1.3和netcore50,也就是說Microsoft.EntityFrameworkCore可以被這三種平台的程序集引用,比如你的程序集frameworks中只配置了net451,照樣可以引用Microsoft.EntityFrameworkCore程序集,只不過只能在 Windows 上運行,不能跨平台而已,一個程序集不同平台的代碼寫法:
#if DNX451 //Code here for dnx451 #elif DNXCORE50 //code here for dnxcore50 #endif
imports的解釋是(來自 Frameworks and imports sections in project.json: what are they?):imports is a way to use packages that were not designed for that framework. Basically you tell it "Use those targets even though they don't seem to be supported. I know what I'm doing". 簡單來說,就是兼容本程序集配置平台所不支持的平台,有點繞,我們做一個測試就清楚了:

如上圖的配置,為什么frameworks配置了netcoreapp1.0會出現錯誤?因為我們引用的Microsoft.EntityFrameworkCore程序包並不完全支持netcoreapp1.0平台,所以我們需要在netcoreapp1.0下增加"imports": ["net451"]配置,其作用就是使之兼容,當然現在只是兼容平台的配置,以后完善之后,這個配置會去掉的。

imports 的一段配置:
"netcoreapp1.0": { "imports": [ "net461", "portable-net45+win81" ] }
首先,imports 可以配置多個節點,portable-net45+win81是什么意思?portable 的意思是便攜式的,在之前的博文中有提及,意思就是自身發布不攜帶依賴的程序包,而是使用系統中安裝配置的,net45就是上面說的frameworks配置,win81是系統平台的意思,但不只是特指 Windows 8.1 系統。
| Platform | NuGet identifier |
|---|---|
| .NET Framework 2.0 - 4.6 | net20 - net46 |
| .NET Core | netcoreapp |
| .NET Micro Framework | netmf |
| Windows 8 | win8, netcore45 |
| Windows 8.1 | win8, netcore451 |
| Windows Phone Silverlight (8, 8.1) | wp8, wp81 |
| Windows Phone 8.1 | wpa8.1 |
| Universal Windows Platform 10 | uap10, netcore50 |
| Silverlight 4, 5 | sl4, sl5 |
| MonoAndroid | monoandroid |
| MonoTouch | monotouch |
| MonoMac | monomac |
| Xamarin iOS | xamarinios |
| Xamarin PlayStation 3 | xamarinpsthree |
| Xamarin PlayStation 4 | xamarinpsfour |
| Xamarin PlayStation Vita | xamarinpsvita |
| Xamarin Watch OS | xamarinwatchos |
| Xamarin TV OS | xamarintvos |
| Xamarin Xbox 360 | xamarinxboxthreesixty |
| Xamarin Xbox One | xamarinxboxone |
最后,再做一個測試,這個我們一般在 ASP.NET 5 Core 1.0 RC1 升級到 RC2 中會遇到的,兩個程序集:
CNBlogs.Ad.Infrastructure.InterfacesCNBlogs.Ad.Infrastructure: 依賴於CNBlogs.Ad.Infrastructure.Interfaces
CNBlogs.Ad.Infrastructure.Interfaces的project.json配置:
{ "version": "1.0.0-*", "description": "CNBlogs.Ad.Infrastructure.Interfaces Class Library", "authors": [ "xishuai" ], "frameworks": { "netcoreapp1.0": { "imports": [ "net451" ] }, "net451": { } }, "dependencies": { "Microsoft.EntityFrameworkCore": "1.0.0-rc2-final", "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final" } }
CNBlogs.Ad.Infrastructure的project.json配置:
{ "version": "1.0.0-*", "description": "CNBlogs.Ad.Infrastructure Class Library", "authors": [ "xishuai" ], "frameworks": { "netcoreapp1.0": { "imports": [ "net451" ] }, "net451": { } }, "dependencies": { "CNBlogs.Ad.Infrastructure.Interfaces": "1.0.0-*", "Microsoft.EntityFrameworkCore": "1.0.0-rc2-final", "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final" } }
幾種測試情況:
CNBlogs.Ad.Infrastructure.Interfaces中的netcoreapp1.0去除"imports": ["net451"]配置:出現錯誤,上面有過分析,因為Microsoft.EntityFrameworkCore並不完全支持netcoreapp1.0。CNBlogs.Ad.Infrastructure.Interfaces去除netcoreapp1.0配置:出現錯誤,因為CNBlogs.Ad.Infrastructure配置了netcoreapp1.0,而引用的CNBlogs.Ad.Infrastructure.Interfaces卻支持net451。CNBlogs.Ad.Infrastructure.Interfaces去除net451配置:出現錯誤,同上,因為CNBlogs.Ad.Infrastructure配置了net451,而引用的CNBlogs.Ad.Infrastructure.Interfaces卻支持netcoreapp1.0。CNBlogs.Ad.Infrastructure去除netcoreapp1.0配置:成功,因為依賴的CNBlogs.Ad.Infrastructure支持net451。CNBlogs.Ad.Infrastructure去除net451配置:出現成功,同上,因為依賴的CNBlogs.Ad.Infrastructure支持netcoreapp1.0。
綜合上面的測試,簡單來說,就是程序包的運行平台或環境取決於底層的引用,底層的引用指的是你自己項目中的程序包,而不是基礎類庫和微軟開發的程序包,因為它們都支持多平台,比如上面的Microsoft.EntityFrameworkCore程序包。
另外,如果你的程序包frameworks配置的是net451,它其實和 .NET Core 沒多大關系了,因為它使用的是 .NET Framework 和 Desktop CLR,而不是 CoreCLR 和 CoreFx,即使你項目中使用的是 .NET Core RC2 的程序包。
參考資料:
- Project.json definition dnx451 vs .dotnet (4.51)
- Target Frameworks
- Project.json Frameworks
- What frameworks are available in ASP.NET Core (ASP.NET 5) applications?
- .NET Platform Standard
- Frameworks and imports sections in project.json: what are they?
- All about httpRuntime targetFramework
- Project.json Usage
