使用 Directory.Build 来消除项目文件中的重复配置

使用 Directory.Build 来消除项目文件中的重复配置

Intro

如果解决方案里的项目比较多的话,往往会有很多重复的项目属性,通常我们可以使用独立的 props 属性文件来配置公用的属性,而一般的属性文件都需要手动的 Import 到项目文件中,而 MSBuild 支持自动导入我们要介绍的 Directory.Build.props中的配置,所以通常我们可以使用 Directory.Build.props 来减少项目中重复的属性

DirectoryBuild

什么是 Directory.Build 呢?

Directory.Build 文件是放在某一个目录下,其中的配置针对这个目录下所有的项目都生效,并且 MSBuild 运行的时候会自动引入,不需要显式地在项目文件中引入,主要分成 Directory.Build.propsDirectory.Build.targets 两类,在很多开源项目包括微软的开源项目都有用到这个来简化项目配置,.props 文件是属性文件,通常定义公用的属性,导入时机较早,项目中的定义可以覆盖掉其中的配置,.targets 是目标文件,通常定义一些自定义的 MSBuild Task,导入时间稍后,可以用来覆盖项目文件中的定义

通常我只是用到 Directory.Build.props 来配置公用的属性

下面是一个项目文件中的一部分:

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework><LangVersion>latest</LangVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings></PropertyGroup>
</Project>

上面 TargetFramwork/Nullable/ImplicitUsings 是一个 MSBuild 属性,需要声明在 PropertyGroup

如果一个解决方案中有很多个项目,那么这些可能就都是重复项了,这时候使用 Directory.Build.props 就会比较方便,比如说 ImplicitUsing 这一属性,这个属性是用来启用 .NET 6 里的隐式命名空间引用的,但是从 .NET 6 RC1 默认是禁用的,需要显式声明 <ImplicitUsings>enable</ImplicitUsings> 来启用,如果项目里的项目都是需要启用的,那就可以直接声明在 Directory.Build.props 中,放在项目根目录下,如下所示:

<Project><PropertyGroup><LangVersion>latest</LangVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings></PropertyGroup>
</Project>

除了 PropertyGroup 之外,我们也可以定义 <ItemGroup>,下面就是一个示例:

<Project><PropertyGroup><LangVersion>latest</LangVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings></PropertyGroup><ItemGroup><Using Include="WeihanLi.Common"/><Using Include="WeihanLi.Common.Helpers"/><Using Include="WeihanLi.Extensions"/></ItemGroup>
</Project>

这样我们可以把公用的命名空间定义在 Directory.Build.props 上, MSBuild 会按目录结构依次寻找上层的 Directory.Build.props,找到第一个之后就会停止再往上寻找,下面是一个示例

c:\users\username\code\test\case1
c:\users\username\code\test
c:\users\username\code
c:\users\username
c:\users
c:\

如果项目较多可以使用多层 Directory.Build.props,下面是一个示例:

\MySolution.slnDirectory.Build.props     (1)\srcDirectory.Build.props   (2-src)\Project1\Project2\testDirectory.Build.props   (2-test)\Project1Tests\Project2Tests

所有项目 (1) 的通用属性、src 项目 (2-src) 的通用属性,以及 test 项目 (2-test) 的通用属性

前面我们提到过,MSBuild 对于指定项目找到第一个 Directory.Build.props 就会停止再向上寻找 Directory.Build.props 如果要同时使用多级 Directory.Build.props 则需要显式导入上层的 Directory.Build.props

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

Sample

下面我们来看一些使用示例吧

Sample1

在稍微复杂一些项目,往往会引用很多的 Nuget 包,而一些项目的版本可能是有关系的,有些包的版本是一致的,此时我们可以考虑定义一个属性,而在包版本的地方则引用这个属性

项目根目录下 Directory.Build.props 内容

<PropertyGroup><LangVersion>latest</LangVersion><Nullable>enable</Nullable><EFVersion>6.0.0-rc.1.*</EFVersion>
</PropertyGroup>

项目文件中内容:

<ItemGroup><PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(EFVersion)" /><PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="$(EFVersion)" /><PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="$(EFVersion)" />
</ItemGroup>

这样我们如果需要更新 EF 的版本,我们只需要更新 Directory.Build.props 文件中的 EFVersion 这个属性就可以了,详细配置可以参考:https://github.com/WeihanLi/WeihanLi.EntityFramework

Sample2

我们再来看一个多个层级使用的示例,项目结构如下所示:

Directory.Build.props
--src
--tests
--Directory.Build.props
----UnitTest
----IntegrationTest

98bdfdb18d7dc02b1726046a8febedd7.png

项目根目录下 Directory.Build.props,主要定义 package 相同的属性配置以及启用可控引用类型,隐式命名空间和公用的命名空间

<Project><PropertyGroup><LangVersion>latest</LangVersion><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><PackageIcon>icon.png</PackageIcon><PackageTags>HTTPie http https curl rest</PackageTags><GenerateDocumentationFile>false</GenerateDocumentationFile><PackageLicenseExpression>MIT</PackageLicenseExpression><RepositoryType>git</RepositoryType><RepositoryUrl>https://github.com/WeihanLi/dotnet-httpie</RepositoryUrl><PackageProjectUrl>https://github.com/WeihanLi/dotnet-httpie</PackageProjectUrl><Product>dotnet-HTTPie</Product><Authors>WeihanLi</Authors><PackageReleaseNotes>https://github.com/WeihanLi/dotnet-httpie/tree/main/docs/ReleaseNotes.md</PackageReleaseNotes><Copyright>Copyright 2021 (c) WeihanLi</Copyright></PropertyGroup><ItemGroup><Using Include="WeihanLi.Common"/><Using Include="WeihanLi.Common.Helpers"/><Using Include="WeihanLi.Extensions"/></ItemGroup>
</Project>

tests 目录下 Directory.Build.props,定义了测试项目公用的命名空间,并引入了上一层 Directory.Build.props 中的属性

<Project><Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" /><ItemGroup><Using Include="FluentAssertions"/><Using Include="Xunit"/></ItemGroup>
</Project>

IntegrationTest 项目文件,引入自己需要的命名空间引用

<ItemGroup><Using Include="HTTPie"/><Using Include="HTTPie.Implement"/><Using Include="HTTPie.Middleware"/><Using Include="HTTPie.Models"/><Using Include="HTTPie.Utilities"/>
</ItemGroup>

具体配置可以参考:https://github.com/WeihanLi/dotnet-httpie

More

使用好 Directory.Build.props 可以简化项目配置,使得项目更容易维护,如果还没用起来的可以尝试一下哈

References

  • https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?WT.mc_id=DT-MVP-5004222&view=vs-2019

  • https://github.com/WeihanLi/SparkTodo/blob/master/Directory.Build.props

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/net6sample

  • https://github.com/WeihanLi/WeihanLi.EntityFramework/blob/dev/Directory.Build.props

  • https://github.com/WeihanLi/dotnet-httpie/blob/dev/Directory.Build.props

  • https://github.com/WeihanLi/dotnet-httpie/blob/dev/tests/Directory.Build.props

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 批量更新和批量插入

1. 批量更新 update table_name set field_name CASE id WHEN id1 THEN field_value, WHEN id1 THEN field_value END 2.批量插入 insert into table_name (field1_name, field2_name) values(field1_value, field2_name) , (field1_value, field2_name)

chromium关闭更新_Win10今年最重磅更新!Win10 2004正式版详尽体验

今年首个Windows 10正式版更新于近日上架MSDN&#xff0c;版本号最终确定为Build 19041.208(v2004)&#xff0c;这是一个RTM版本&#xff0c;也就是送到OEM厂商压盘的正式版本&#xff0c;向用户正式推送的时候不会再有什么功能变化。按照微软的一贯逻辑&#xff0c;上半年更新…

Android网络通信的六种方式示例代码

表1展示了Android SDK中的一些与网络有关的API包名表1. Android SDK 网络包包 描述 API LevelJava.net 提供与联网有关的类&#xff0c;包括流和数据包&#xff0…

技术分享 | 业务模板的技术实践

源宝导读&#xff1a;“业务模板”作为天际建模平台3.0推出的重要特性&#xff0c;它将元数据复用发挥到了极致&#xff0c;通过业务模板几乎可以覆盖整个建模元数据开发流程&#xff0c;提供业务场景级别的复用能力。本文将介绍“业务模板”的设计原理、实现方案和应用场景。一…

为什么那么好的女孩子还单身?

1 终于知道家里的吃的都是怎么没的了&#xff01;2 我的小鱼干&#xff01;快给我&#xff01;3 这几只狗子真是太皮了&#xff01;4 您点的肉香满溢披萨到了~5 一位新手爸爸分享了自己关于为人父母的感悟6 应采儿&#xff1a;为什么那么好的女孩子还单身&#xff1f; 陈小春&a…

php上传预览源码,php批量上传五[带预览]-PHP源码

《script》ec(2);《script》$path$_SERVER["DOCUMENT_ROOT"];//服务器路径$i 0;foreach ($_FILES["pictures"]["error"] as $key > $error) {if ($error UPLOAD_ERR_OK) {$upload_file$_FILES[pictures][tmp_name][$key];//文件被上传后在服…

RHCS创建高可用集群apche服务器

实验环境&#xff1a; 系统版本&#xff1a;RHEL5.4 将selinux关闭&#xff0c;刷新iptables -F 配置yum仓库 192.168.0.25 station25.example.com 宿主机 192.168.0.24 station24.example.com 节点(虚拟机) 192.168.0.39 station39.example.com 节点(…

成不了天才,但为何也没成人材?(转)

长期以来&#xff0c;"软件业"一直被视为"智力密集"型的"朝阳"产业&#xff0c;大多数从业者都受过高等教育&#xff0c;其平均素质居于社会各行业的前列&#xff0c;这个产业的顶尖人物被公众视为"知识英雄"&#xff0c;比如微软公司…

python rgb转lab_从RGB转换到LAB色彩空间 - 深入了解L * A * B *值的范围?

在OpenCV(Python)中将图像从RGB转换为LAB时&#xff0c;我无法找到有关L * A * B *值范围的文档。寻找一些确认我的见解是正确的&#xff0c;因为这些数字相当奇特。我的轻度结果是从0-255&#xff0c;但对于a和b我分别得到了42-226和20-223。我知道这些数值不需要有一个预定的…

oracle怎么删除lob对象,Oracle系列:LOB大对象处理

Oracle系列&#xff1a;LOB大对象处理Oracle系列&#xff1a;LOB大对象处理主要是用来存储大量数据的数据库字段&#xff0c;最大可以存储4G字节的非结构化数据。主要介绍字符类型和二进制文件类型LOB数据的存储&#xff0c;单独介绍二进制类型LOB数据的存储。一&#xff0c;Or…

.NET 6 RC2 版本发布

原文&#xff1a;bit.ly/3FS9xm7作者&#xff1a;Richard日期&#xff1a;2021-10-12翻译&#xff1a;精致码农-王亮说明&#xff1a;文中有大量的超链接&#xff0c;这些链接在公众号文章中被自动剔除&#xff0c;一部分包含超链接列表的小段落被我删减了&#xff0c;如果你对…

prototype.js 和jquery-1.6.2.js冲突问题解决方法

在写项目中同时用到了jquery-1.6.2.js和prototype.js两个js文件&#xff0c;使用$的时候冲突。解决方法&#xff1a; 首先引入jquery-1.6.2.js&#xff0c;然后重定义$。 <script type"text/javascript"> js$; $aa; </script> 然后在引入prototype.…

最诡异数学悖论:1+1=1

全世界只有3.14 % 的人关注了爆炸吧知识今天&#xff0c;8岁表妹的老师给她奖励了一块大巧克力&#xff0c;超模君打趣她能不能分给我点&#xff0c;遭到残忍拒绝&#xff0c;超模君很愤怒&#xff0c;暗下决心要神不知鬼不觉地吃上表妹的巧克力。超模君趁表妹在认真做作业的时…

JS URL Parser

为什么80%的码农都做不了架构师&#xff1f;>>> /** *param {string} url 完整的URL地址 *returns {object} 自定义的对象 *description 用法示例&#xff1a;var myURL parseURL(http://abc.com:8080/dir/index.html?id255&mhello#top); myURL.fileindex.ht…

如何使用Instruments诊断App(Swift版):起步

2019独角兽企业重金招聘Python工程师标准>>> 本文由Mr_cyz&#xff08;博客&#xff09;翻译自raywenderlich&#xff0c;欢迎参与我们的翻译活动。原文&#xff1a;Instruments Tutorial with Swift: Getting Started 更新记录&#xff1a;该教程由 James Frost 更…

tcp抓包返回fin_TCP/IP学习二TCP链接建立与断开

今天详细学习下TCP链接的三次握手四次挥手&#xff0c;因为开发web服务还是会经常遇到一些网络问题的。其实这方面的资料很多&#xff0c;可能我们看过很多次但也忘了无数次[捂脸]&#xff0c;这次我主要通过抓包例子来展示这个过程。TCP传输控制协议(TransmissionControlProto…

设置vim

1、配置文件的位置 在目录 /etc/ 下面&#xff0c;有个名为vimrc的文件&#xff0c;这是系统中公共的vim配置文件&#xff0c;对所有用户都有效。而在每个用户的主目录下&#xff0c;都可以自己建立私有的配置文件&#xff0c;命名为&#xff1a;“.vimrc”。例如&#xff0…

70%的单身女孩都是这样想的!

1 父爱如山&#xff0c;山就是杵在那里一动不动&#xff01;2 3 单身的女孩不要着急4 哎呀&#xff0c;没有两条小鱼干是起不来了&#xff01;5 一分钟教你画二哈&#xff0c;这次真的厉害了&#xff01;6 披着羊皮的狼&#xff1f;&#xff1f;&#xff1f;你点的每个赞&#…

.NET基金会讨论 .NET 开源事业之路

【编者按】从闭源走向开源&#xff0c;.NET 背后都发生了哪些有趣的故事。本文采访了 6 位微软 .NET 团队成员&#xff0c;分享他们在 GitHub 以及建立 .NET 开源项目的经历。作者 | Richard Lander 译者 | 弯月出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff0…

oracle的排序分页,oracle 排序分页 高效sql语句

最好还是利用分析函数row_number() over ( partition by col1 order by col2 )比如想取出100-150条记录,按照tname排序select tname,tabtype from ( select tname,tabtype,row_number() over ( order by tname ) rn from tab)where rn between 100 and 150;2. 直接使用rownum 虚…