Comparaison des propriétés et des éléments
Les propriétés et les éléments MSBuild sont utilisés pour passer des informations aux tâches, évaluer des conditions et stocker des valeurs qui peuvent être référencées dans tout le fichier projet.
Les propriétés sont des paires nom-valeur.Pour plus d'informations, consultez Propriétés MSBuild.
Les éléments sont des objets qui représentent généralement des fichiers.Les objets d'élément peuvent avoir des collections de métadonnées associées.Les métadonnées sont des paires nom-valeur.Pour plus d'informations, consultez Éléments MSBuild.
Propriétés scalaires et types d'éléments vectoriels
Étant donné que les propriétés MSBuild sont des paires nom-valeur qui ont seulement une valeur de chaîne, elles sont souvent décrites comme scalaires.Étant donné que les types d'éléments MSBuild sont des listes d'éléments, ils sont souvent décrits comme vectoriels.Toutefois, dans la pratique, les propriétés peuvent représenter plusieurs valeurs, et les types d'éléments peuvent avoir zéro ou un élément.
Injection de dépendance cible
Pour savoir comment les propriétés peuvent représenter plusieurs valeurs, utilisez un modèle d'utilisation commun pour l'ajout d'une cible à une liste de cibles à générer.Cette liste est généralement représentée par une valeur de propriété, dans laquelle les noms des cibles sont séparés par des points-virgules.
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
En général, la propriété BuildDependsOn est utilisée comme l'argument d'un attribut DependsOnTargets cible, qui le convertit efficacement en une liste d'éléments.Cette propriété peut être substituée pour ajouter une cible ou modifier l'ordre d'exécution des cibles.Par exemple :
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
CustomBuild;
</BuildDependsOn>
</PropertyGroup>
ajoute la cible CustomBuild à la liste des cibles, en affectant à BuildDependsOn la valeur BeforeBuild;CoreBuild;AfterBuild;CustomBuild.
À partir de MSBuild 4.0, l'injection de dépendance cible est déconseillée.Utilisez les attributs AfterTargets et BeforeTargets à la place.Pour plus d'informations, consultez Ordre de génération des cibles.
Conversions entre des chaînes et des listes d'éléments
MSBuild exécute des conversions vers et depuis des types d'éléments et des valeurs de chaîne en fonction des besoins.Pour savoir comment une liste d'éléments peut devenir une valeur de chaîne, pensez à ce qui arrive lorsqu'un type d'élément est utilisé comme valeur d'une propriété MSBuild :
<ItemGroup>
<OutputDir Include="KeyFiles\;Certificates\" />
</ItemGroup>
<PropertyGroup>
<OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>
Le type d'élément OutputDir a un attribut Include avec la valeur « KeyFiles\;Certificates\ ».MSBuild analyse cette chaîne en deux éléments : Keyfiles\ et Certificates\.Lorsque le type d'élément OutputDir est utilisé comme valeur de la propriété OutputDirList, MSBuild convertit ou « aplanit » le type d'élément en chaîne séparée par un point-virgule « KeyFiles\;Certificates\ ».
Propriétés et éléments dans des tâches
Les propriétés et les éléments sont utilisés comme entrées et sorties des tâches MSBuild.Pour plus d'informations, consultez Tâches MSBuild.
Les propriétés sont passées aux tâches en tant qu'attributs.Dans la tâche, une propriété MSBuild est représentée par un type de propriété dont la valeur peut être convertie depuis et vers une chaîne.Les types de propriété pris en charge incluent bool, char, DateTime, Decimal, Double, int, string et tout type que ChangeType peut gérer.
Les éléments sont passés aux tâches comme objets ITaskItem.Dans la tâche, ItemSpec représente la valeur de l'élément et GetMetadata extrait ses métadonnées.
La liste d'éléments d'un type d'élément peut être passée comme un tableau d'objets ITaskItem.Depuis .NET Framework 3.5, des éléments peuvent être supprimés d'une liste d'éléments dans une cible à l'aide de l'attribut Remove.Étant donné que des éléments peuvent être supprimés d'une liste d'éléments, il est possible qu'un type d'élément ait zéro élément.Si une liste d'éléments est passée à une tâche, le code dans la tâche doit vérifier cette possibilité.
Ordre d'évaluation des propriétés et des éléments
Pendant la phase d'évaluation d'une build, les fichiers importés sont incorporés à la build dans l'ordre dans lequel ils s'affichent.Les propriétés et les éléments sont définis en trois phases, dans l'ordre suivant :
Les propriétés sont définies et modifiées dans l'ordre dans lequel elles s'affichent.
Les définitions d'élément sont définies et modifiées dans l'ordre dans lequel elles s'affichent.
Les éléments sont définis et modifiés dans l'ordre dans lequel ils s'affichent.
Pendant la phase d'exécution d'une build, les propriétés et les éléments définis dans des cibles sont évalués ensemble en une seule phase, dans l'ordre dans lequel ils s'affichent.
Toutefois, l'opération ne s'arrête pas là.Lorsqu'une propriété, une définition d'élément ou un élément est défini, sa valeur est évaluée.L'évaluateur d'expression développe la chaîne qui spécifie la valeur.L'expansion de chaîne dépend de la phase de génération.Voici un ordre d'évaluation plus détaillé des propriétés et des éléments :
Pendant la phase d'évaluation d'une build :
Les propriétés sont définies et modifiées dans l'ordre dans lequel elles s'affichent.Les fonctions de propriétés sont exécutées.Des valeurs de propriétés au format $(NomPropriété) sont développées dans des expressions.La propriété a pour valeur l'expression développée.
Les définitions d'élément sont définies et modifiées dans l'ordre dans lequel elles s'affichent.Des fonctions de propriétés ont déjà été développées dans des expressions.Les métadonnées ont pour valeur les expressions développées.
Les types d'éléments sont définis et modifiés dans l'ordre dans lequel ils s'affichent.Les valeurs d'élément au format @(TypeÉlément) sont développées.Les transformations d'élément sont également développées.Des valeurs et des fonctions de propriétés ont déjà été développées dans des expressions.La liste d'éléments et les métadonnées ont pour valeur les expressions développées.
Pendant la phase d'exécution d'une build :
- Les propriétés et les éléments définis dans des cibles sont évalués ensemble dans l'ordre dans lequel ils s'affichent.Les fonctions de propriétés sont exécutées et les valeurs de propriétés sont développées dans des expressions.Des valeurs d'élément et des transformations d'élément sont également développées.Les propriétés, les types d'éléments et les métadonnées ont pour valeur les expressions développées.
Effets discrets de l'ordre d'évaluation
Dans la phase d'évaluation d'une build, l'évaluation des propriétés précède l'évaluation des éléments.Néanmoins, les propriétés peuvent avoir des valeurs qui semblent dépendre des valeurs d'éléments.Prenons le script suivant :
<ItemGroup>
<KeyFile Include="KeyFile.cs">
<Version>1.0.0.3</Version>
</KeyFile>
</ItemGroup>
<PropertyGroup>
<KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<Target Name="AfterBuild">
<Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>
L'exécution de la tâche Message affiche ce message :
KeyFileVersion: 1.0.0.3
En effet, la valeur de KeyFileVersion correspond à la chaîne « @(KeyFile->'%(Version)') ».Dans la mesure où l'élément et les transformations d'élément n'ont pas été développés lorsque la propriété a été définie pour la première fois, la valeur de la chaîne non développée a été assignée à la propriété KeyFileVersion.
Pendant la phase d'exécution de la build, lorsqu'il traite la tâche Message, MSBuild développe la chaîne « @(KeyFile->'%(Version)') » pour générer « 1.0.0.3 ».
Notez que le même message apparaîtrait même si l'ordre des groupes d'éléments et de propriétés était inversé.
Prenons un deuxième exemple, pour savoir ce qui peut arriver lorsque les groupes de propriétés et d'éléments se trouvent à l'intérieur des cibles :
<Target Name="AfterBuild">
<PropertyGroup>
<KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<ItemGroup>
<KeyFile Include="KeyFile.cs">
<Version>1.0.0.3</Version>
</KeyFile>
</ItemGroup>
<Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>
La tâche Message affiche ce message :
KeyFileVersion:
En effet, pendant la phase d'exécution de la build, les groupes de propriétés et d'éléments définis dans des cibles sont évalués de haut en bas en même temps.Lorsque KeyFileVersion est défini, KeyFile est inconnu.Par conséquent, la transformation d'élément se développe vers une chaîne vide.
Dans ce cas, l'inversion de l'ordre des groupes de propriétés et d'éléments restaure le message d'origine :
<Target Name="AfterBuild">
<ItemGroup>
<KeyFile Include="KeyFile.cs">
<Version>1.0.0.3</Version>
</KeyFile>
</ItemGroup>
<PropertyGroup>
<KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>
La valeur de KeyFileVersion est « 1.0.0.3 » et non « @(KeyFile->'%(Version)') ».La tâche Message affiche ce message :
KeyFileVersion: 1.0.0.3