开发者

Possible to reverse order of ItemGroup elements?

In MSBuild 3.5, is it possible to reverse the order elements in an ItemGroup?

Example

I have 2 projects. One can be built independently the other is dependent on the first. Each project references its specific items in a .targets file.

project_A.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_A.dll">
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>

    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_A.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

project_B.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_B.dll">
            <ApplicationName>App_B</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>

    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_B.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_B</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

project_A.proj

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="project_A.targets" />

    <Import Project="Common.targets" />
</Project>

project_B.proj

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="project_A.targets" />

    <Import Project="project_B.targets" />

    <Import Project="Common.targets" />
</Project>

The Problem

In this scenario the problem arises during the Task processing @(AssembliesToDeploy) because Assembly_B.dll needs to be deployed before Assembly_A.dll.

Processing @(AssembliesToRemove) works fine because here the assemblies are in the right order (remove Assembly_A.dll before Assembly_B.dll).

What I tried to do

I tried to influence the order of @(AssembliesToDeploy) by modifying project_B.targets like this:

<ItemGroup>
    <AssembliesToDeploy Include="Assembly_B.dll">
        <AssemblyType>SomeType</AssemblyType>
        <ApplicationName>App_B</ApplicationName>
    </AssembliesToDeploy>
    <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
</ItemGroup>

but when using project_B.targets inside project_B.proj the order inside @(AssembliesToDeploy) still remained Assembly开发者_StackOverflow_A.dll;Assembly_B.dll.

Edit

As MadGnome points out this cannot work because I'll end up with duplicates in @(AssembliesToDeploy)

Is there a solution which would allow to reuse my .targets i.e not copying all ItemGroup elements to all .targets files?


You just have to include project_B.targets before project_A.

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="project_B.targets" />
  <Import Project="project_A.targets" />    

  <Import Project="Common.targets" />
</Project>

I think there is a mistake in this code :

<ItemGroup>
  <!-- Generates duplicates if used with Import -->
  <AssembliesToDeploy Include="@(AssembliesToDeploy)" />

  <AssembliesToDeploy Include="Assembly_B.dll">
    <AssemblyType>SomeType</AssemblyType>
    <ApplicationName>App_B</ApplicationName>
  </AssembliesToDeploy>
</ItemGroup>

You are using Import, so you if you use the code above you'll have duplicates in AssembliesToDeploy.


Adopting from MadGnomes answer I decided to split the ItemGroups into separate .target files.

project_A_REMOVE.targets

<Project xmlns="...">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_A.dll">
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>
</Project>

project_A_DEPLOY.targets

<Project xmlns="...">
    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_A.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

and the same for project_B.targets.

The project_B.proj now looks like this

<Project DefaultTargets="Start" xmlns="...">
    <Import Project="project_A_REMOVE.targets" />
    <Import Project="project_B_REMOVE.targets" />

    <Import Project="project_B_DEPLOY.targets" />
    <Import Project="project_A_DEPLOY.targets" />

    <Import Project="Common.targets" />
</Project>

Since my real solution consist of some 58 projects this will result in a lot of .targets. Even more so because I have to keep a common .targets for every project.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜