这个想法是,如果
BuildConfigurations
元数据中未指定活动/当前构建配置,则将引用的项目作为包拉取。否则,它将被添加为 ProjectReference
。在这种情况下,MaterialBalance
和Pricing
应作为包拉出。
这是代码;
<ItemGroup>
<CustomProjectReference Include="..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj" PackageName="ProjectName.MaterialBalance" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,MaterialBalance"/>
<CustomProjectReference Include="..\ProjectName.Pricing\ProjectName.Pricing.csproj" PackageName="ProjectName.Pricing" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,Pricing"/>
</ItemGroup>
<Target Name="SetPackageReferences" BeforeTargets="CollectPackageReferences">
<ItemGroup>
<PackageReference Include="@(CustomProjectReference->'%(PackageName)')" Version="%(CustomProjectReference.PackageVersion)" Condition="!$([System.String]::new('%(CustomProjectReference.BuildConfigurations)').Contains('$(Configuration)'))" />
</ItemGroup>
</Target>
提供的目标
SetPackageReferences
正在按预期工作,包已恢复并且项目已构建。但是 Visual Studio 依赖关系树 无法按预期工作,我已将其报告为问题 here。
如果我可以在目标/评估时间之外添加具有特定条件的包引用,我就不会出现依赖关系树问题。
您是否认为有任何替代方法可以在目标/评估时间之外实现此目的?在 Target 之外,功能非常有限,这不起作用,需要批处理;
<ItemGroup>
<PackageReference Include="@(CustomProjectReference->'%(PackageName)')" Version="%(CustomProjectReference.PackageVersion)" Condition="!$([System.String]::new('%(CustomProjectReference.BuildConfigurations)').Contains('$(Configuration)'))" />
</ItemGroup>
%
字符可能会令人困惑。
%
引入了元数据引用,但元数据引用的含义可能根据上下文而有很大不同。转变
@(CustomProjectReference->'%(PackageName)')
是
transform的示例。像
@(CustomProjectReference)
这样的项目集合引用可以选择进行转换。给定以下消息任务:
<Message Text="@(CustomProjectReference)" />
<Message Text="@(CustomProjectReference->'%(PackageName)')" />
<Message Text="@(CustomProjectReference->'name is %(Filename) and ext is %(Extension)')" />
输出将是:
..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj;..\ProjectName.Pricing\ProjectName.Pricing.csproj
ProjectName.MaterialBalance;ProjectName.Pricing
name is ProjectName.MaterialBalance and ext is .csproj;name is ProjectName.Pricing and ext is .csproj
批处理
元数据自参考
使用
Remove <ItemGroup>
<CustomProjectReference Include="..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj" PackageName="ProjectName.MaterialBalance" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,MaterialBalance"/>
<CustomProjectReference Include="..\ProjectName.Pricing\ProjectName.Pricing.csproj" PackageName="ProjectName.Pricing" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,Pricing"/>
</ItemGroup>
有两件事需要实现:
将
CustomProjectReference
PackageReference
。根据 $(Configuration)
<ItemGroup>
<_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" />
</ItemGroup>
@(CustomProjectReference)
中项目的现有元数据将被继承。如果您将消息任务放入适当的目标中,您可以测试并查看。
<Message Text="@(_tmpPackageRef->'%(Identity) %(BuildConfigurations)', '%0d%0a')" />
将会显示
ProjectName.MaterialBalance Debug,Release,Prod,MaterialBalance
ProjectName.Pricing Debug,Release,Prod,Pricing
过滤很棘手,因为
BuildConfigurations
元数据的值是一个列表。但
Contains()
测试的结果可以是元数据,可以在映射时创建。可以添加 HasConfig
可用于过滤。 (请注意,此处不能使用否定运算符 !
。) <ItemGroup>
<_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" HasConfig="$([System.String]::new('%(BuildConfigurations)').Contains('$(Configuration)'))" />
</ItemGroup>
将它们放在一起可能如下所示:
<ItemGroup>
<_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" HasConfig="$([System.String]::new('%(BuildConfigurations)').Contains('$(Configuration)'))" />
<_Tester Include="True" HasConfig="%(Identity)" />
<_tmpPackageRef Remove="@(_Tester)" MatchOnMetadata="HasConfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="@(_tmpPackageRef)" />
</ItemGroup>
_Tester
物品收藏仅适用于
Remove
。 _Tester
的目的是提供一个HasConfig
,Include
的值可以是任何值。我选择包含 True
和自我参考来设置 HasConfig
。匹配适用于 True
(不是 False
),因为匹配的项目将被删除,仅留下 $(Configuration)
的当前值不在 BuildConfigurations
中的项目。