Dotnet 构建条件包参考

Dotnet Build Conditional PackageReference

我需要在构建后 运行 一个 ILRepack MSBuild 任务,并在我们的项目文件中添加了以下目标:

  <Target Name="MergeNet45" AfterTargets="Build" Condition="'$(TargetFramework)' == 'net45' and '$(RunILRepack)' == 'true'">
    <Exec WorkingDirectory="$(OutputDir)" Command="$(ILRepack) /internalize /out:$(OutputDir)$(AssemblyName).dll $(OutputDir)$(AssemblyName).dll $(OutputDir)\System.IdentityModel.Tokens.Jwt.dll  $(OutputDir)\Microsoft.IdentityModel.JsonWebTokens.dll $(OutputDir)\Microsoft.IdentityModel.Tokens.dll $(OutputDir)\Microsoft.IdentityModel.Logging.dll $(OutputDir)\Newtonsoft.Json.dll" />
  </Target>

  <Target Name="MergeStandard" AfterTargets="Build" Condition="'$(TargetFramework)' == 'netstandard2.0' and '$(RunILRepack)' == 'true'">
    <Exec WorkingDirectory="$(OutputDir)" Command="$(ILRepack) /internalize /lib:$(NetStandardLoc) /out:$(OutputDir)$(AssemblyName).dll $(OutputDir)$(AssemblyName).dll $(OutputDir)\System.IdentityModel.Tokens.Jwt.dll  $(OutputDir)\Microsoft.IdentityModel.JsonWebTokens.dll $(OutputDir)\Microsoft.IdentityModel.Tokens.dll $(OutputDir)\Microsoft.IdentityModel.Logging.dll $(OutputDir)\Newtonsoft.Json.dll $(OutputDir)\Microsoft.Extensions.Configuration.Json.dll" />
  </Target>

现在对于单元测试项目,我们有一些参考需要包含在我们没有执行 ILRepack 的情况下,例如来自 Visual Studio.

的构建

对于正常构建,我想传递 /p:RunILRepack=false 以允许我 运行 单元测试、获取代码覆盖率并对代码执行 sonarqube 分析。

在单元测试项目中,我声明了以下内容:

  <PropertyGroup Condition="'$(RunILRepack)' == ''">
    <RunILRepack>false</RunILRepack>
  </PropertyGroup>
  <Choose>
    <When Condition="'$(RunILRepack)' == 'false'">
      <ItemGroup>
        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.2.4"  />
        <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Logging" Version="5.2.4" />
        <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
      </ItemGroup>
    </When>
  </Choose>

我尝试过但没有成功的备选方案是:

      <ItemGroup Condition="'$(RunILRepack)' == 'false'">
        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.2.4"  />
        <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Logging" Version="5.2.4" />
        <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
      </ItemGroup>

并将 PackageReferences 移动到单独的 .proj 文件,并对导入设置条件。

我的上述工作按预期进行。

第二次,我想通过 /p:RunILRepack=true,这次它应该 运行 ILRepack 并在我们的主 dll 和包中包含一些程序集引用,以便我们可以发布包。

现在,对于第二次构建,我总是会收到如下构建错误:

error CS0433: The type 'RsaSecurityKey' exists in both 'Microsoft.IdentityModel.Tokens, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' and 'Company.Namespace.AssemblName, Version=1.1.2.0, Culture=neutral, PublicKeyToken=null'

error CS0433: The type 'RsaSecurityKey' exists in both...

error CS0433: The type 'JsonWebKey' exists in both ...

所以这意味着这些引用已被导入,尽管情况不应该如此。

到目前为止,我在通过 /p:RunILRepack=true 时能够构建项目的唯一方法是完全删除上面列出的包引用。

如何包含那些 PackageReference 项,以便它们仅在我们设置 /p:RunILRepack=false 时被导入?

我最终通过引入一个额外的构建配置解决了这个问题,然后更改了在该配置上忽略的项目组条件:

  <Choose>
    <When Condition="'$(Configuration)' != 'ReleaseILMerge'">
      <ItemGroup>
        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.2.4" />
        <PackageReference Include="Microsoft.IdentityModel.Logging" Version="5.2.4" />
        <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
      </ItemGroup>
    </When>
  </Choose>

这是唯一有效的方法。我不知道为什么使用属性不起作用。这一定是 MSBuild 或 Nuget 中的错误。