Generating a cross-product with MSBuild

Have you ever wanted to create a cross-product of two item groups in TeamBuild? Aaron Hallberg has a post in which he explains two possible ways of doing it. I struggled with the same problem a few days ago and found another solution that doesn’t involve creating your own MSBuild Task but still keeps the “collection aspect of batching”.

Aaron has a simple lab example that I will use to explain my approach. The goal is to create a cross product of the Foo and Bar collections and then print out the result. My solution follows:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="PrintFooAndBar"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

<ItemGroup>
<Foo Include="foo1">
<FooMetadata>1</FooMetadata>
</Foo>
<Foo Include="foo2">
<FooMetadata>2</FooMetadata>
</Foo>
</ItemGroup>

<ItemGroup>
<Bar Include="bar1">
<BarMetadata>a</BarMetadata>
</Bar>
<Bar Include="bar2">
<BarMetadata>b</BarMetadata>
</Bar>
</ItemGroup>

<Target Name="PrintFooAndBar">
<!-- Create a new list of Items that contain the cross product of Bar and Foo -->
<CreateItem Include="@(Bar)"
AdditionalMetadata="FooMetadata=%(Foo.FooMetadata)">
<Output ItemName="InternalBar" TaskParameter="Include"/>
</CreateItem>

<!-- Print the contents of the new list -->
<Message Importance="high"
Text="FooMetadata=%(InternalBar.FooMetadata), BarMetadata=%(InternalBar.BarMetadata)" />
</Target>
</Project>

I simply use the CreateItem task to merge the two collections into a new collection that contains the metadata from both. I then use this new collection to print out the messages!

If more information is needed from the collections (maybe you want to keep the %Identity data from Foo) you can simply add more stuff to the AdditionalMetadata attribute (“Foo=%(Foo.Identity);FooMetadata=%(Foo.FooMetadata)”)



One response to “Generating a cross-product with MSBuild”

Leave a reply to chmarroc Cancel reply

About Me

Consultant, Solution Architect, Developer.

Do note that this blog is very, very old. Please consider that before you follow any of the advice in here!

Newsletter