个箱子您 發表於 2025-4-10 23:30:00

.NET SDK样式项目打包时如何将项目引用转为包依赖

<h2 id="项目背景">项目背景</h2>
<p>最近开发一组类库,大约会有五六个项目。一个Core,加上若干面向不同产品的实现库,A/B/C/D...它们都依赖Core.</p>
<p>首先,我想统一版本号,这个容易,通过Directory.Build.props设置。</p>
<p>其次,每个库要单独发包。</p>
<p>问题是在开发阶段,子项目都是通过项目引用Core的,便于调试,怎么实现在打包时自动加上对Core包的依赖?</p>
<p>经过试验,可以总结三种方法:</p>
<h3 id="一生成时将-projectreference-转为-nuget-依赖项-not-work">一、生成时将 ProjectReference 转为 NuGet 依赖项 (Not Work)</h3>
<p>这个是DeepSeek推荐的方案,但很遗憾,我没试验成功。<br>
它的项目结构是这样的:</p>
<pre><code>&lt;ItemGroup&gt;
&lt;ProjectReference Include="..\Core\MyProject.Core.csproj" &gt;
    &lt;PrivateAssets&gt;all&lt;/PrivateAssets&gt;
    &lt;Publish&gt;true&lt;/Publish&gt;
    &lt;Version&gt;$(PackageVersion)&lt;/Version&gt;
    &lt;PackageId&gt;MyProject.Core&lt;/PackageId&gt;
&lt;/ProjectReference&gt;
&lt;/ItemGroup&gt;


&lt;Target Name="ForcePackageReferenceConversion" BeforeTargets="GenerateNuspec"&gt;
&lt;ItemGroup&gt;
    &lt;_PackageReferencesToAdd Include="@(ProjectReference-&gt;WithMetadataValue('Publish', 'true'))"&gt;
      &lt;PackageId&gt;%(PackageId)&lt;/PackageId&gt;
      &lt;Version&gt;%(Version)&lt;/Version&gt;
    &lt;/_PackageReferencesToAdd&gt;
    &lt;PackageReference Include="@(_PackageReferencesToAdd-&gt;'%(PackageId)')" Version="%(Version)" /&gt;
&lt;/ItemGroup&gt;
&lt;/Target&gt;
</code></pre>
<p>它的核心思路是生成.nuspec前将项目引用强制转换在包引用。</p>
<p>至于为什么没成功,Github Copilot的解释如下:</p>
<p><em>This is a common scenario, but unfortunately, MSBuild and NuGet do not natively support automatically converting a <projectreference> to a <packagereference> at pack time. The custom target approach (like ForcePackageReferenceConversion) does not work because NuGet determines dependencies before your target runs.</packagereference></projectreference></em></p>
<h3 id="二按条件引用">二、按条件引用</h3>
<p>项目结构:</p>
<pre><code>&lt;ItemGroup&gt;
&lt;!-- 开发时使用 ProjectReference --&gt;
&lt;ProjectReference Include="..\Core\MyProject.Core.csproj"
                  Condition="'$(IsPackaging)' != 'true'" /&gt;

&lt;!-- 打包时使用 PackageReference --&gt;
&lt;PackageReference Include="MyProject.Core"
                  Version="$(PackageVersion)"
                  Condition="'$(IsPackaging)' == 'true'" /&gt;
&lt;/ItemGroup&gt;
</code></pre>
<p>然后使用命令生成:</p>
<pre><code>dotnet pack -p:IsPackaging=true
</code></pre>
<p>此法可行,推荐使用。</p>
<h3 id="三指定nuspec文件">三、指定.nuspec文件</h3>
<p>最后,我又想到了用传统的.nuspec文件。(我很喜欢以前的包管理方式,packages.config/nuspec,不理解为什么MS非要把所有的东西都往project文件里塞。)</p>
<p>项目结构:</p>
<pre><code>&lt;!-- 指定自定义 nuspec 文件路径 --&gt;
    &lt;NuspecFile&gt;My.nuspec&lt;/NuspecFile&gt;
    &lt;!-- 传递 MSBuild 属性到 nuspec 中的变量 --&gt;
    &lt;NuspecProperties&gt;$(NuspecProperties);
      id=$(PackageId);
      version=$(Version);
      company=$(Company);
      authors=$(Authors);
      product=$(Product);
      copyright=$(Copyright);
      license=$(PackageLicenseExpression);
      projectUrl=$(PackageProjectUrl);
      repositoryUrl=$(RepositoryUrl);
      repositoryType=$(RepositoryType);
      icon=$(PackageIcon);
      config=$(Configuration)
    &lt;/NuspecProperties&gt;
</code></pre>
<p>它将Directory.Build.props中定义的属性一一赋给nuspec.<br>
验证可行,此法适合制作复杂的包。</p>


</div>
<div id="MySignature" role="contentinfo">
    <div id="AllanboltSignature">         

<div>作者:CnSharp工作室</div>      

<div>出处:http://www.cnblogs.com/cnsharp/</div>      

<div>本文版权归CnSharp.com所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.</div>      


</div><br><br>
来源:https://www.cnblogs.com/cnsharp/p/18819771
頁: [1]
查看完整版本: .NET SDK样式项目打包时如何将项目引用转为包依赖