.NET Core系列 : 2 、project.json 這葫蘆裏賣的什麼藥

.NET Core系列 : 一、.NET Core 環境搭建和命令行CLI入門 介紹了.NET Core環境,本文介紹.NET Core中最重要的一個配置文件project.json的相關內容。們可使用.NET Core 的dotnet 命令行接口(CLI)dotnet new命令建立一個應用,也能夠用Visual Studio 2015 update 3建立一個應用,他們都有一個project.json ,它是項目的配置文件,相似以前的*.csrpoj文件。Project.json 是一個新的項目文件,它的功能大部分與 *.*PROJ 文件重疊。它可標識項目引用、版本選項(如版本號)等事項,並可標識要編譯的平臺,例如,是 .NET Core 仍是 .NET Framework。心細的你可能已經發現了他們所建立出來的project.json 文件的內容有不少都不同。咱們下面就來看下這個文件的內容,project.json 的官方文檔 https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json

project.json

首先,從咱們 經過 Visual Studio 建立的項目 xproj  的 project.json︰html

 

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },git

  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0"
    }
  },github

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}算法

 

dotnet new 命令建立項目的 project.json:npm

 

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}json

他們結構上看是類似的,可是具體內容上有很大的不一樣的地方,他們都有4個頂級的屬性:version, buildOptions, dependencies 和 framework。.NET Core 項目結構中最重要的文件多是 project.json。此文件旨在:服務器

替換 NuGet 文件管理器 package.config 文件,它可標識項目的 NuGet 引用。
指定項目支持的框架,以及有關如何爲特定框架構建項目的配置詳細信息。
標識獨立應用的目標平臺,它含有其全部依賴項,包括對應平臺所需的特定於平臺的 .NET Core 運行時。或者,若是項目是可移植應用,project.json 可標識項目會在目標計算機(將在其上運行程序集)上安裝的框架。
這三個任務分佈在 project.json 中的四個主要部分(根據項目類型,我將Frameworks 和 dependencies合併爲功能重疊):架構

Version

version 這個屬性是你所要構建的組件的最小的元數據,其餘元數據包括name,title,description ,copyright 等, name 選項默認狀況下使用的是父文件夾名稱,你能夠經過name 這個屬性給它取個你想要的名字。app

 

buildOptions

buildOptions節點定義瞭如何編譯和編譯哪些文件等,也就是編譯選項。編譯選項部分包含一些有用的屬性。首先是 emitEntryPoint,這用來肯定是否生成可執行二進制文件或 exe 。默認狀況下,調用 Program.Main() 方法將被調用來運行你的應用。框架

我發現一個有趣的屬性是"debugType":"portable"。Visual Studio 代碼調試器必須設置這個屬性纔可以工做的。但這也意味着您的應用程序將以不一樣的方式發佈,具體哪一個值取決於您在此處的設置。簡要的能夠看前一篇文章的dotnet publish 節,更多的介紹在後面發佈應用程序的時候介紹。

Frameworks 和 dependencies

dependencies此部分列出了你的項目所依賴的各個 NuGet 包,包括所述依賴項的版本號。可使用通配符指定版本號,從而你能夠容許 NuGet 包管理器還原自動下載與通配符相匹配的「最新版本」。版本號的空引號對錶示「使用最新可用項」。咱們建立的項目能夠針對一個或者多個Framework(好比咱們但願建立的能夠同時在.NET Framework和.NET Core上運行),支持的Framework定義在frameworks節點下。若是添加了多個Framework,並非說最終生成的應用能夠同時在這 些Framework中運行,而是說源文件在編譯的時候會針對這些Framework生成對應的程序集。對於傳統的.NET項目來講,若是咱們須要調用某個API,須要添加所在程序集的引用。對於.NET Core來講,全部使用到的程序集都被打包成一個NuGet包,因此針對程序集的直接依賴轉變成針對某個NuGet包的依賴。針對NuGet的依賴主要有 兩種類型,一種是針對全部Framework的,它們會直接定義在dependencies節點下,另外一種則是針對某個具體Framework的, 定義爲當前Framework節點下的dependencies子節點。對於獨立應用,運行時部分指定將支持的 OS,所以可指定要綁定到應用程序的運行時庫。

從上面2個project.json 文件能夠看出Frameworks 和 dependencies 存在依賴關係。他們是能夠嵌套的,在最高一級的依賴項,將是全部的Frameworks所依賴的,也能夠針對一個具體的Framework 構建它的依賴關係,不一樣的Framework使用不一樣版本的依賴項。看上面的例子,咱們看到Visual Studio和dotnet CLI版本定義的是相同的結果,只是兩種不一樣的表達方式。

 

Microsoft.NETCore.App

咱們來仔細看下 Microsoft.NETCore.App:

"Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0"
   }
這是一個依賴項,平臺的依賴,它也是Nuget包,其中包含了一堆系統庫的NuGet程序包,包含.netcore的基礎運行時和基礎類庫。 文章 

Running .NET Core apps on multiple frameworks and What the Target Framework Monikers (TFMs) are about 詳細的介紹了具體的內容。

 

netcoreapp1.0

咱們再來仔細看下  netcoreapp1.0:

"frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
框架netcoreapp1.0 是個多目標框架對象名字(TFM)值,除了有經典的net45,net46,如今又有了一些新的像netcoreapp1.0,文章 

Running .NET Core apps on multiple frameworks and What the Target Framework Monikers (TFMs) are about 有更詳細的說明。

 

NETStandard.Library

上面咱們建立的項目是個應用程序,當咱們回到類庫的時候,在依賴項裏會發現一個NETStandard.Library:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable"
  },
  "dependencies": {},
  "frameworks": {
    "netstandard1.6": {
      "dependencies": {
        "NETStandard.Library": "1.6.0"
      }
    }
  }
}

這也是一個NuGet 程序包: https://www.nuget.org/packages/NETStandard.Library/,裏面包含了多個目標版本,相似於老的PCL方法,之後就使用NETStandard.Library替代了PCL,咱們有了一個更加統一的版本控制策略。

本質上來講,NETStandard.Library 是一個目標最低支持基礎類庫,這樣就能夠更好的向前兼容性,在現有的平臺出現新的版本時(如.net core 1.1 甚至 2.0)而無需從新發布新的變化。具體參考 https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md ,目前最新的表格:

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   *      

如何理解這個表格

  • 若是一個類庫指定.NET平臺標準1.3版本,那麼它僅可以運行在.NET Framework 4.6或更新的框架、Universal Windows Platform 10(UWP)、DNX Core 5.0和Mono/Xamarin這些平臺上。
  • 若是一個類庫指定.NET平臺標準1.3版本,那麼它可以引用(原文:consume)全部來自以前的.NET平臺標準的版本(1.二、1.一、1.0)。

 

關於project.json 的更多信息

.NET Core項目依賴所有使用NuGet,要求使用NuGet 3.0版本,默認使用nuget.org 做爲源。在安裝VS2015 Update3時,.NET Core所需的官方依賴包都已經安裝在了(默認安裝)C:\Program Files (x86)\Microsoft SDKs\NuGetPackages目錄下,在nuget管理中也能夠看到這是默認的離線包目錄,咱們須要什麼樣的包只要把它複製到這個目錄,在nuget管理中的程序包源選擇離線的源便可。執行dotnet restore命令後項目會根據project.json文件配置來恢復項目依賴包,同時就會生成新的project.json.lock文件。

 

project.json.lock 

Project.json.lock 存儲編譯所需文件的列表(一般爲 NuGet 引用)。與 project.json 文件不一樣,它包括特定的包版本號,可支持通配符。若是沒有 project.json.lock,將完整還原包。Project.json.lock 包括包圖片以及本地下載的其餘與包相關的數據(已還原)。它的工做方式 和 npm以及 RubyGems很是類似,你能夠把這個文件簽入版本庫,也能夠不簽入,但此文件不存在時,將運行 NuGet restore 還原以從新建立。此文件列爲 Visual Studio 中 project.json 的子項。

 

HellodotnetCore.xproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  </PropertyGroup>

  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
  <PropertyGroup Label="Globals">
    <ProjectGuid>34ee435f-9fda-4fb2-b4fb-a3203939f0c5</ProjectGuid>
    <RootNamespace>HellodotnetCore</RootNamespace>
    <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
    <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
  </PropertyGroup>

  <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>
  </PropertyGroup>
  <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

 

和以往的csproj 文件同樣,這個文件架起Visual Studio 和MSBuild溝通的橋樑。HellodotnetCore.xproj 定義構建項目時將發生的事項。最新版本可導入 Microsoft.DotNet.targets,它定義了利用新 DotNet.exe 命令的構建任務。與過去的 MSBuild proj 文件不一樣,xproj 文件很是小,由於大部分信息已(暫時)移到 project.json。不事後續這個文件要被csproj 替代,也許就在不久的未來的Visual Studio 2016上面就變成了csproj。

 

global.json

global.json是一個有待探究的神奇配置文件,我最喜歡的一個功能是全新的支持調試和單步執行,甚至能夠實時修改包的源代碼。假設你有公司範圍的「框架」程序集,能夠在衆多團隊之間共享。可是,

可是,框架包其實是開源的,所以公司內(或者,甚至更好,公司外部)的任何人員都可進行完善和更改。如今,想像你若是爲此框架引用 NuGet 包,但有時懷疑可能存在須要修復的缺陷或可能存在一個批准的加強功能。一般,這須要獨立於項目/解決方案處理組件中的源代碼。相反,若是你可以下載源代碼並隨時開發將其更新爲集成式體驗 - 甚至單步調試,而不依賴於符號服務器或 PDB 文件是否可用,會怎麼樣? 幸運地是,Visual Studio 2015 支持此關鍵場景。

例如,想象你想要調試 GitHub 上可用的 Microsoft.Extensions.Logging 包。要在項目中對其進行添加和調試,你須要下載(可能使用 git clone 或 git submodule 命令)源代碼。接下來,爲了使 Visual Studio 知曉在何處查找源代碼,你須要編輯 global.json 項目節點,如將「submodules\Logging」添加到查看的目錄列表:

{
  "projects": [ "src", "test", "submodules\Logging" ],
  "sdk": {
    "version": "1.0.0-*"
  }
}
固然,你能夠提供完整路徑(例如,你未將代碼克隆到子目錄)。可是,請注意,目錄分隔符是兩個反斜槓 (\\) 或單個正斜線(如 c:/users/geffzhang/documents/visual studio2015/Projects/Microsoft.Extensions.Logging)。

更新並保存 global.json 後,一旦 Visual Studio 成功找到源代碼,它會自動將項目添加到你的解決方案,使你能夠調試到源代碼。

這裏使用了一種很是棒的算法來肯定要加載的源代碼目錄:

  1. 若是 global.json 中指定的任何源代碼位置包含的文件夾具備與包相同的名稱(如 Microsoft.Extensions.Logging),且此文件夾包含名爲 project.json 的文件,調試程序將使用此文件夾及其內部的源文件。
  2. 不然,會加載包文件夾中編譯的二進制程序。

 

 

本文簡要介紹了.NET Core項目中最爲重要的一個配置文件project.json的內容和相關的工具,類庫等基礎信息,下篇文章咱們來聊聊如何構建多個Project的解決方案的內容。

相關文章
相關標籤/搜索