MSBuild: By Example—Introducing Custom Metadata


Jump to: navigation, search
CSharp-Online.NET:Articles
Visual Studio Articles

MSBuild: By Example

© 2006 Hashimi & Hashimi

Introducing Custom Metadata

Metadata, the data that describes data, seems to be becoming just as important as the data itself. It seems that every new technology has metadata incorporated into its plan. MSBuild is certainly no different! In fact, MSBuild heavily relies on metadata. Earlier we showed how to access and use well-known metadata. Well-known metadata is "automagically" generated for your items. Some examples of well-known metadata in MSBuild are the full path of the file and its directory. You are not limited only to the well-known metadata, though. You can add custom metadata to items as well. Refer to the following ItemGroup:

<ItemGroup>
    <MDForm Include="MetaDataFrm.cs">
        <Name>Sayed Ibrahim Hashimi</Name>
        <Email>sayed.hashimi@gmail.com</Email>
    </MDForm>
    <MDFormOther Include="..\..\**\MSBuild1\*.cs">
        <Name>Sayed Y. Hashimi</Name>
        <Email>hashimi_sayed@gmail.com</Email>
    </MDFormOther>
</ItemGroup>

This item group has two items defined: MDForm and MDFormOther. With the files that are included in the items, the author information is provided in the Name and Email elements. The name and e-mail address are provided for those responsible for the classes included. How can you use this information in your MSBuild project files? Refer to the following target that prints the author information for these items:

<Target Name="PrintAuthorInfo">
    <Message Text="@(MDForm->'%(Filename)%(Extension)')" />
    <Message Text="%09Name:%09@(MDForm->'%(Name)')"/>
    <Message Text="%09Email:%09@(MDForm->'%(Email)')"/>
 
    <Message Text="%0D%0A"/>  <!--New line -->
    <Message Text="@(MDFormOther->'%(Filename)%(Extension)', '  ')" />
 
    <Message Text="%09Name:%09%(MDFormOther.Name)"/>
    <Message Text="%09Email:%09%(MDFormOther.Email)"/>
    <!-- Don't use this will print name/e-mail
         once for each file included in the item
    <Message Text="%09Name:%09@(MDFormOther->'%(Name)')"/>
    <Message Text="%09Email:%09@(MDFormOther->'%(Email)')"/>
    -->
</Target> 

This target will first print the name and e-mail address for the MDForm author. The Message item that prints the name and e-mail is <Message Text="%09Name:%09@(MDForm->'%(Name)')"/>. This Message item contains some formatting to make it more readable (which is covered in the "Formatting Your Output" section if you are wondering about all the weird characters). If you strip away the formatting, you are left with <Message Text="Name: @(MDForm->'%(Name)')"/>. So, you just learned how to access the Name metadata element. It is just like how you access well-known metadata.

Did you notice that the name/e-mail is printed differently in the MDFormOther item as opposed to the technique used in the MDForm item? Here are the different ways the name is printed, minus the formatting:

<Message Text="Name: @(MDForm->'%(Name)')"/>
<Message Text="Name: %(MDFormOther.Name)"/> 

In the MDForm item, you are accessing the name as a vector value, and in MDFormOther you are accessing it as a scalar value. We discuss the difference between scalar and vector values in further detail in the "Understanding the Difference Between @ and %" section. We will briefly review the concepts here for completeness. When you use the @ syntax, you are saying you are expecting a vector-valued result. That is, if three items are included, you want each to be processed separately. So, if there is another item in the MDForm include list, then you will see the name printed one time for each include. With the % syntax, you are requesting the result in a single string. In this scenario, the MDFormOther technique is the correct approach.

The difference between vector and scalar values can be confusing; if you need more information, see the next section.


Previous_Page_.gif Next_Page_.gif


Personal tools