Как использовать элементы MSBuild ItemGroup в качестве отдельных элементов, таких как Свойства? - PullRequest
2 голосов
/ 02 марта 2011

Так что я немного привык к написанию в MSBuild.

Мне нравится идея хранить вещи в ItemGroups, потому что его легко перебирать, и вы можете иметь несколько полей.

Это делает их своего рода классом (больше похожим на структуру), но они реагируют на синтаксис итераций целей и задач таким образом, что они напоминают лямбда-выражения.

Однако я продолжаючтобы столкнуться с ситуацией, когда я хочу получить доступ к значению определенного элемента в группе элементов, то есть к нему, как к свойству.

В этом случае я сталкиваюсь с вопросом, как изолировать одинэлемент в группе.

Когда группа элементов пакетируется в цели или задаче, из-за адресации с использованием имени метаданных или из-за адресации с общим именем группы элементов, вы можете использовать значение 'current'item т.е. @ (ItemsName) или% (MetaDataName).

Но я хочу сделать что-то вроде: использовать группу Item в качестве класса System.Configuration, который содержит значения записей в разделе файла конфигурации,Поэтому обычным было бы присвоить имя самой ItemGroup, чтобы оно совпадало с именем раздела в файле конфигурации.однако ItemGroup не является адресуемым элементом, который доступен через интерфейс механизма сборки, только сами элементы являются адресуемыми.

Было бы неплохо по отдельности назвать элементы в ItemGroup, а не называть их одинаково.и используйте поле «Включить» или поле метаданных, чтобы различать их.Это заставляет их вести себя как свойства в том смысле, что они индивидуально адресуемы как отдельные элементы.так что вы могли бы легко использовать их значения в Условиях следующим образом: '@ (UniqueItemName ->'% (Value) ').

Однако тогда итеративные функции по существу теряются.

Для суженияв этом случае предположим, что у меня есть файл конфигурации, который считывается в группу элементов с помощью задачи xml, так что имена элементов в разделе становятся именами элементов в группе элементов, а атрибуты каждого элемента файла конфигурации являются атрибутами, которые становятся метаданными:

<configItemFlag name="displayDebugMessages" value="true" note="use with abandon" />
<configItemFlag name="displaySecurityValueMessages" value="false" note="use with caution" />

Когда я хочу проверить это в условии, мне нужно сузить его до чего-то вроде этого:

<Messge Text="Debug Message: you are debugging!" Condition="'@(configItemFlag->'%(Name)')' == 'displayDebugMessages' AND '@(configItemFlag->'%(Value)')' == 'true'/>

Но это только оценивает сравнение и часто неоценивать до одного логического значения.

Так есть ли способ синтаксически довести это до надежного теста?

Ответы [ 2 ]

3 голосов
/ 02 марта 2011

Это работает для того, что вы пытаетесь сделать?

<ItemGroup>
  <ConfigItemFlag Include="displayDebugMessages">
    <Value>true</Value>
    <Note>use with abandon</Note>
  </ConfigItemFlag>
  <ConfigItemFlag Include="displaySecurityValueMessages">
    <Value>false</Value>
    <Note>use with caution</Note>
  </ConfigItemFlag>
</ItemGroup>

<Target Name="Build">
  <Message
    Condition="
      '%(ConfigItemFlag.Identity)' == 'displayDebugMessages' AND
      '%(Value)' == 'true'"
    Text="Debug Message: you are debugging, %(Note)!"
    /> 
</Target>

Выход:

Build:
  Debug Message: you are debugging, use with abandon!

(ответ на комментарий)

... единственное, что я могу предложить, чтобы иметь возможность использовать мета в качестве свойств, не так уж велико, если только цель не будет интенсивно использовать их повсюду. В основном это включает в себя выравнивание каждого элемента к свойствам путем пакетирования по элементу и создания локальных свойств для каждой партии.

<Target Name="BuildOne"
  Outputs="%(ConfigItemFlag.Identity)">
  <!-- flatten this batch to properties -->
  <PropertyGroup>
    <_Identity>%(ConfigItemFlag.Identity)</_Identity>
    <_Value>%(ConfigItemFlag.Value)</_Value>
    <_Note>%(ConfigItemFlag.Note)</_Note>
  </PropertyGroup>
  <!-- use meta as properties -->
  <Message
    Condition="
      '$(_Identity)' == 'displayDebugMessages' AND
      '$(_Value)' == 'true'"
    Text="Debug Message: you are debugging, $(_Note)!"
    /> 
</Target>
<Target Name="Build" DependsOnTargets="BuildOne"
  />
1 голос
/ 03 марта 2011

Кажется, вы сталкиваетесь с некоторыми ограничениями языка сценариев msbuild. Задумывались ли вы о написании пользовательского задания для выполнения того, что вы ищете? Таким образом, вы сможете использовать всю мощь полноценного языка программирования для простой условной проверки, которую вы хотите выполнить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...