>我注意到当我使用类库模板创建项目时,.csproj包含Microsoft.Common.props的导入
<Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props')" />
但是,当我使用单元测试项目模板创建项目时,它不存在。
那么Microsoft.Common.props是做什么的呢?它对项目有何好处?
它做了很多事情,并引入了一部分构建逻辑。
实际上,"标准".NET 项目有两个重要的导入:"Microsoft.Common.props
"和"Microsoft.Common.targets
"(后者可能隐式包含在特定于项目类型的导入文件中)。
基本思想是将构建逻辑拆分为两部分,一部分在项目内容之前导入(这将是.props
),另一部分包含在项目内容之后(.targets
)。
Microsoft.Common.props
将根据约定定义一些属性 - 例如,为当前配置设置默认值(例如,如果从命令行构建时未指定配置,则为Debug
构建)。
它还导入作为扩展安装的其他文件到 msbuild/vs 工具安装或项目 - 例如,NuGet 4+ 将其用于PackageReference
样式的项目。
Microsoft.Common.props
导入设置完所有默认值后,轮到项目根据用户选择(和项目模板)更改默认值,以及定义生成过程所需的其他一些属性和项。
然后,项目必须导入一个.targets
文件,该文件定义执行项目生成所需的 msbuild 逻辑。这是通过Microsoft.Common.targets
(以及它选择导入的文件)完成的。 在此导入之后,需要覆盖来自此文件的逻辑的任何内容都需要指定 - 这就是为什么 VS 的项目模板具有自定义AfterBuild
目标的注释区域。由于AfterBuild
已通过公共目标定义,因此需要在此导入后重写它(或使用自定义名称并添加AfterTargets="AfterBuild"
这是较新的 MSBuild 版本中的首选)。
默认值和逻辑的.props
/.targets
拆分也大量用于自定义构建扩展和msbuild文件的命名约定,这些文件应该在项目的顶部(.props
)和底部(.targets
)导入。
在为.NET Core引入但也可以与.NET Framework一起使用的"基于SDK"的项目中,通过导入Sdk.props
和Sdk.targets
文件来扩展此概念 - 分别在项目内容之前和之后。一组约定有助于查找这些文件,甚至允许您通过在项目文件上指定属性来省略<Import>
元素:<Project Sdk="Microsoft.NET.Sdk">...</Project>
。这些导入将定义比Microsoft.Common.props
更多的默认值,允许非常小和更易读的项目文件。(目前,只有.NET Core/.NET Standard和 ASP.NET Core项目模板使用此格式,因为VS 2017使用的项目系统与经典csproj文件不同)