当 A 项目引用 B 项目,那么使用 Visual Studio 或者 MSBuild 编译 A 项目之前就会确保 B 项目已经编译完毕。通常我们指定这种引用是因为 A 项目确实在运行期间需要 B 项目生成的程序集。
但是,现在 B 项目可能仅仅只是一个工具项目,或者说 A 项目编译之后的程序集并不需要 B,仅仅只是将 B 打到一个包中,那么我们其实需要的仅仅是 B 项目先编译而已。
本文介绍如何影响项目的编译顺序,而不带来项目实际引用。
依然在项目中使用往常习惯的方法设置项目引用:
但是,在项目引用设置完成之后,需要打开项目的项目文件(.csproj)给 ProjectReference
节点加上 ReferenceOutputAssembly
的属性设置,将其值设置为 false
。这表示仅仅是项目引用,而不将项目的任何输出程序集作为此项目的依赖。
<ItemGroup>
<ProjectReference Include="..\Walterlv.Demo.Analyzer\Walterlv.Demo.Analyzer.csproj" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\Walterlv.Demo.Build\Walterlv.Demo.Build.csproj" ReferenceOutputAssembly="false" />
ItemGroup>
上面的 ProjectReference
是 Sdk 风格的 csproj 文件中的项目引用。即便不是 Sdk 风格,也是一样的加这个属性。
当然,你写多行也是可以的:
<ItemGroup>
<ProjectReference Include="..\Walterlv.Demo.Analyzer\Walterlv.Demo.Analyzer.csproj">
<ReferenceOutputAssembly>falseReferenceOutputAssembly>
ProjectReference>
<ProjectReference Include="..\Walterlv.Demo.Build\Walterlv.Demo.Build.csproj">
<ReferenceOutputAssembly>falseReferenceOutputAssembly>
ProjectReference>
ItemGroup>
这种做法有两个非常棒的用途:
ReferenceOutputAssembly
来引用项目,最终生成的 NuGet 包中就不会生成对这些项目的依赖。此方法可能会是更加常用的方法,但兼容性不那么好,可能在部分旧版本的 Visual Studio 或者 .NET Core 版本的 dotnet build
命令下不容易工作起来。
在解决方案上右键,然后选择“设置项目依赖”:
然后在弹出的项目依赖对话框中选择一个项目的依赖:
这时,如果看看解决方案文件(.sln)则可以看到多出了 ProjectDependencies
区:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo", "Walterlv.Demo\Walterlv.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
ProjectSection(ProjectDependencies) = postProject
{98FF9756-B95A-4FDB-9858-5106F486FBF3} = {98FF9756-B95A-4FDB-9858-5106F486FBF3}
EndProjectSection
EndProject
更多关于 sln 文件的理解,可以阅读我的另一篇博客:
使用 ReferenceOutputAssembly
属性设置的方式是将项目的编译顺序指定到项目文件中的,这意味着如果使用命令行单独编译这个项目,也是能获得提前编译目标项目的效果的,而不需要打开对应的解决方案编译才可以获得改变编译顺序的效果。
不过使用 ReferenceOutputAssembly
的一个缺陷是,必须要求目标框架能够匹配。比如 .NET Core 2.1 的项目就不能引用 .NET Core 3.0 或者 .NET Framework 4.8 的项目。
而在解决方案级别设置项目依赖则没有框架上的限制。无论你的项目是什么框架,都可以在编译之前先编译好依赖的项目。只是旧版本的 MSBuild 工具和 dotnet build
不支持 ProjectDependencies
这样的解决方案节点,会导致要么不识别这样的项目依赖(从而实际上并没有影响编译顺序)或者无法完成编译(例如出现 Error parsing the nested project section in solution file. 错误)。
参考资料
我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。
如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。