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.0
instead).dnx451
: DNX SDK running on .Net 4.5.1 (Desktop CLR / Full BCL and FCL) (deprecated, usenet451
instead).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,dotnet
before) 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 RC2dotnet
is deprecated, usenetstandard
instead.
先看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.Interfaces
CNBlogs.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