好问题!我在我的书籍和一篇博客文章《可重用的MSBuild脚本要素:验证》中深入讨论了这个问题。我的方法将涵盖属性和项。
以下是总结。在共享的`.targets`文件中创建一个验证目标,它应该是文件中声明的第一个目标之一,以便用户可以轻松找到它。
属性
在验证目标中,为您的属性定义如下:
<_RequiredProperties Include="Root">
<Value>$(Root)</Value>
</_RequiredProperties>
我将属性名放入Include
中,将其值放入Value
元数据中。我这样做的原因是为了检测Value
是否为空,然后使用include值向用户报告缺失属性的名称。
项目
在目标位置内,将所需项目放入像这样的项目中:
<_RequiredItems Include="AllConfigurations">
<RequiredValue>@(AllConfigurations)</RequiredValue>
</_RequiredItems>
与属性类似,在包含文件中,您需要将项的名称和要检查的值放置在RequiredValue
元数据中。在此示例中,它只是检查确保AllConfiguraitons
项不为空。如果您想确保所有项都指定了给定的元数据值,则可以执行以下操作:
<_RequiredItems Include = "AllConfigurations.Configuration">
<RequiredValue>%(AllConfigurations.Configuration </RequiredValue>
</_RequiredItems>
如果您想确保文件存在,则可以添加额外的元数据 RequiredFilePath。
<_RequiredItems Include ="ProjectsToBuild">
<RequiredValue>%(ProjectsToBuild.Identity)</RequiredValue>
<RequiredFilePath>%(ProjectsToBuild.Identity)</RequiredFilePath>
</_RequiredItems>
验证
以下是进行验证所需的内容:
完整示例
以下是完整示例:
<Target Name="ValidateBuildSettings">
<ItemGroup>
<_RequiredProperties Include="Root">
<Value>$(Root)</Value>
</_RequiredProperties>
<_RequiredProperties Include="BuildInstallRoot">
<Value>$(BuildInstallRoot)</Value>
</_RequiredProperties>
<_RequiredProperties Include="SourceRoot">
<Value>$(SourceRoot)</Value>
</_RequiredProperties>
<!--
_RequiredItems is the item where required items should be placed.
The following metadata is significant:
REQUIRED METADATA:
Identity = This will basically be used to identify the specific required item
RequiredValue = This is the specific value that will be validated to exist
OPTIONAL METADATA
RequiredFilePath = Populate this with a path that should exists, if it is not empty
then it will be checked to exist on disk.
-->
<_RequiredItems Include="AllConfigurations">
<RequiredValue>@(AllConfigurations)</RequiredValue>
</_RequiredItems>
<_RequiredItems Include = "AllConfigurations.Configuration">
<RequiredValue>%(AllConfigurations.Configuration </RequiredValue>
</_RequiredItems>
<_RequiredItems Include ="ProjectsToBuild">
<RequiredValue>%(ProjectsToBuild.Identity)</RequiredValue>
<RequiredFilePath>%(ProjectsToBuild.Identity)</RequiredFilePath>
</_RequiredItems>
</ItemGroup>
<!-- Raise an error if any value in _RequiredProperties is missing -->
<Error Condition =" '%(_RequiredProperties.Value)'=='' "
Text=" Missing required property [%(_RequiredProperties.Identity)]" />
<!-- Raise an error if any value in _RequiredItems is empty -->
<Error Condition = " '%(_RequiredItems.RequiredValue)'=='' "
Text = " Missing required item value [%(_RequiredItems.Identity)] " />
<!-- Validate any file/directory that should exist -->
<Error Condition = " '%(_RequiredItems.RequiredFilePath)' != '' and !Exists('%(_RequiredItems.RequiredFilePath)') "
Text = " Unable to find expeceted path [%(_RequiredItems.RequiredFilePath)] on item [%(_RequiredItems.Identity)] " />
</Target>