如何解决此 MSBuild 导入问题?

How to solve this MSBuild import problem?

我有一个 API 可以导入很多模块。这是代码片段:

<Import Project="/CRM/Ticketing/Module.targets" />
<Import Project="/CRM/Customers/Module.targets" />
<Import Project="/CRM/Loyalty/Module.targets" />
<Import Project="/CRM/Club/Module.targets" />

每个 Module.targets 文件定义两个属性并导入一个基础 Module.targets 文件:

<PropertyGroup>
    <Project>CRM</Project>
    <Module>Customers</Module>
</PropertyGroup>

<Import Project="/Base/Module.targets" />

<PropertyGroup>
    <Project>CRM</Project>
    <Module>Club</Module>
</PropertyGroup>

<Import Project="/Base/Module.targets" />

这是基础 Module.targets:

<Project>
  
  <ItemGroup>
    <Reference Include="$(Project).$(Module).Models">
      <HintPath>/$(Project)/$(Module)/Packages/$(Project).$(Module).Models.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="$(Project).$(Module).DataAccess">
      <HintPath>/$(Project)/$(Module)/Packages/$(Project).$(Module).DataAccess.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="$(Project).$(Module).Business">
      <HintPath>/$(Project)/$(Module)/Packages/$(Project).$(Module).Business.dll</HintPath>
      <Private>True</Private>
    </Reference>
  </ItemGroup>
  
  <ItemGroup>
    <Content Include="/$(Project)/$(Module)/Database.json">
      <Link>Database$(Module).json</Link>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

</Project>

问题是 MSBuild 抱怨:

warning MSB4011: "/Base/Module.targets" cannot be imported again. It was already imported at "/CRM/Customers/Project.targets (8,3)". This is most likely a build authoring error. This subsequent import will be ignored. [/CRM/CustomerApi/Api.csproj]

我该如何解决这个问题?

您可以使用所谓的 batching 来执行此操作,这是循环遍历事物的 msbuild 方法。

A.proj:

<Project>
  <ItemGroup>
    <Projects Include="CRM">
      <Module>Ticketing</Module>
    </Projects>
  </ItemGroup>
</Project>

B.proj:

<Project>
  <ItemGroup>
    <Projects Include="CRM">
      <Module>Customers</Module>
    </Projects>
  </ItemGroup>
</Project>

最终项目:

<Project DefaultTargets="Show">

  <Import Project="A.proj"/>
  <Import Project="B.proj"/>

  <ItemGroup>
    <Projects Update="@(Projects)">
      <ReferenceName>%(Identity).%(Module).Models</ReferenceName>
      <ReferenceHintPath>/%(Identity)/%(Module)/Packages/%(Identity).%(Module).Models.dll</ReferenceHintPath>
    </Projects>
    <Reference Include="@(Projects->'%(ReferenceName)')">
      <HintPath>%(ReferenceHintPath)</HintPath>
      <Private>True</Private>
    </Reference>
  </ItemGroup>
  
  <Target Name="Show">
    <Message Text="%(Reference.Identity) %(Reference.HintPath)" />
  </Target>

</Project>

输出:

CRM.Ticketing.Models /CRM/Ticketing/Packages/CRM.Ticketing.Models.dll
CRM.Customers.Models /CRM/Customers/Packages/CRM.Customers.Models.dll

第一个 ItemGroup 遍历项目并为每个项目添加引用名称和路径,然后第二个 ItemGroup 添加实际的引用。