Search code examples
c#msbuildmsbuild-task

Retrieving multiple item metadata with the same name in c# msbuild task


How can I get multiple item metadata with the same name in a c# msbuild task, for example if I were to have:

 <ItemGroup>    
   <Assemblies Include = "S:\SVN\SomeDirectory\src\">
     <excludeAssembly>AssemblyName_1</excludeAssembly>
     <excludeAssembly>AssemblyName_2</excludeAssembly>
     <excludeAssembly>AssemblyName_3</excludeAssembly>
     <excludeAssembly>AssemblyName_4</excludeAssembly>
   </Assemblies>
 </ItemGroup>

How would I get a list of all <excludeAssembly> metadata if normally one would use:

var itemData = itemTask.GetMetadata("excludeAssembly")

to get single metadata values. I need to get a list of <excludeAssembly> values


Solution

  • Metadata is different than item, you can have different metadatas for one item but only one value for a metadata.

    Using Reflector on Microsoft.Build.Engine assembly (BuildItem.EvaluateAllItemMetadata(...)), you see that metadata for an item are stored in a Dictionnary, so for a given metadata name you can have only one value.

    A workaround in your case is too use metadata as name for item, like this:

    <ItemGroup>    
      <Assemblies Include = "S:\SVN\SomeDirectory\src\">
        <excludeAssembly>exludeAssemblySet</excludeAssembly>
      </Assemblies>
    </ItemGroup>
    
    <ItemGroup>
      <exludeAssemblySet Include="AssemblyName_1"/>
      <exludeAssemblySet Include="AssemblyName_2"/>
      <exludeAssemblySet Include="AssemblyName_3"/>
      <exludeAssemblySet Include="AssemblyName_4"/>
    </ItemGroup>
    
    // Approximative syntax, I don't know what you want to do
    var itemData = itemTask.GetMetadata("excludeAssembly");
    BuildItemGroup excludeAssemblies = project.GetEvaluatedItemsByName(itemData);