.NET Core系列 : 1、.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︰

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

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

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

dotnet new 命令创建项目的 project.json:

{
  "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"
    }
  }
}

他们结构上看是相似的,但是具体内容上有很大的不同的地方,他们都有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 这个属性给它取个你想要的名字。

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.2、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的解决方案的内容。

.NET Core系列 : 2 、project.json 这葫芦里卖的什么药的更多相关文章

  1. ASP.NET Core中的project.json何去何从?

    Shawn Wildermuth (https://wildermuth.com/2016/05/12/The-Future-of-project-json-in-ASP-NET-Core) If y ...

  2. .NET Core 工具从 project.json 移动到基于 MSBuild 的项目后的使用

    .NET Core 从preview 4 开始弃用project.json 可以从这下载最新版本: https://github.com/dotnet/cli 使用VS2017 RC新建.net co ...

  3. [C#] .NET Core项目修改project.json来引用其他目录下的源码等文件的办法 & 解决多框架时 project.json 与 app.config冲突的问题

    作者: zyl910 一.缘由 项目规模大了后,经常会出现源码文件分布在不同目录的情况,但.NET Core项目默认只有项目目录下的源码文件,且不支持"Add As Link"方式 ...

  4. .NET Core项目修改project.json来引用其他目录下的源码等文件的办法 & 解决多框架时 project.json 与 app.config冲突的问题

    作者: zyl910 一.缘由 项目规模大了后,经常会出现源码文件分布在不同目录的情况,但.NET Core项目默认只有项目目录下的源码文件,且不支持“Add As Link”方式引入文件.这时需要手 ...

  5. .NET Core系列 :3 、使用多个项目

    通过前面的两篇文章,我们已经知道如何创建新的项目,如何生成并运行我们的应用程序,也知道(大致) project.json 文件中的内容是什么意思.但大多数项目往往也需要多个项目或引用的类库.我们要创建 ...

  6. .NET Core 构建配置文件从 project.json 到 .csproj

    从 .NET Core SDK 1.0 Preview 3 build 004056 开始,.NET Core 弃用 project.json,回归 .csproj,主要原因是为了兼容 MSBuild ...

  7. [asp.net core]project.json(1)

    摘要 前面介绍了使用vs2015新建asp.net core web的内容,这篇文章学习下project.json文件的内容. project.json 原文:https://docs.microso ...

  8. 难以接受你的改变:从project.json到.csproj

    自从微软做了一个艰难的决定——.NET Core彻底放弃project.json,全面改回.csproj——至今,虽然赞美之声不断,但我依然不喜欢也难以接受这样的改变. 难以接受主要有两方面的原因: ...

  9. ASP.NET Core project.json imports 是什么意思?

    示例代码: "frameworks": { "netcoreapp1.0.0": { "imports" : "portable- ...

随机推荐

  1. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  2. 高性能Javascript--脚本的无阻塞加载策略

    Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理U ...

  3. ABP文档 - 异常处理

    文档目录 本节内容: 简介 启用错误处理 非AJAX请求 显示异常 UserFriendlyException Error 模型 AJAX 请求 异常事件 简介 这个文档针对Asp.net Mvc和W ...

  4. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

  5. ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面

    DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认文件,那么前面介绍的StaticFileMiddleware中间件会 ...

  6. ASP.NET MVC开发日常一:SessionID合理清除

    在MVC Web开发中临时存储数据一般会用到Session,Cookie,ViewBag,ViewData,TempData.每个的使用场景是不同,具体区别有空再补上. Session数据最敏感,最需 ...

  7. pdo的使用

    PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口. PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据. PDO随 ...

  8. BPM协同平台解决方案分享

    一.需求分析 企业信息化的过程都是从单纯解决一个业务功能问题,到解决企业内部业务流程问题,再扩展到解决不同业务流程的关联互动问题, 核心是业务的集成和业务的协同,需要有一个统一的业务协同平台. 国内的 ...

  9. Kafka:主要参数详解(转)

    原文地址:http://kafka.apache.org/documentation.html ############################# System ############### ...

  10. 【一起学OpenFoam】01 OpenFoam的优势

    CFD技术发展到今天,已经超过了大半个世纪了,已经涌现出非常多的CFD软件可供人们使用.通用商业CFD软件譬如Fluent.CFX.Star CCM+等在工业上得到了广泛的应用,另外一些专用的软件(如 ...