Neben den bereits vorgestellten Neuerungen
sind auch BeforeTargets und AfterTargets neu in MSBuild 4.0 vorhanden.
Um zu erklären was BeforeTargets und AfterTargets sind, möchte ich einfach noch einmal ein kleines MSBuild 3.5 Buildscript zum Vergleich darstellen.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="SimpleTarget"
InitialTargets="PrintWelcomeMessage"
ToolsVersion="3.5">
<Target Name="PrintWelcomeMessage">
<Message Text="Hello! Welcome to MSBuild tutorial by http://www.dotnet-rocks.de"
Importance="high"/>
<Message Text="STAGE INITIALIZE: $(ExternalProperty)"/>
</Target>
<Target Name="SimpleTarget" DependsOnTargets="PrintWelcomeMessage;JustAnotherTarget">
<Message Text="This target is only for printing a message!"/>
<Message Text="STAGE DEFAULT TARGET: $(ExternalProperty)"/>
<Warning Text="FY"/>
</Target>
<Import Project="$(MSBuildStartupDirectory)\BuildFileToImport.targets"/>
<Target Name="JustAnotherTarget">
<Message Text="This is just another target which displays a message..."/>
<Message Text="STAGE DEFAULT TARGET DEPENDENCY: $(ExternalProperty)"/>
</Target>
</Project>
Wie man dem SimpleTarget entnehmen kann, bestehen zwei Abhängigkeiten, die MSBuild zur Laufzeit validieren und ausführen muss, bevor die Ausführung des SimpleTargets gestartet werden kann.
Das Target PrintWelcomeMessage wird als InitialTarget beim ersten Aufruf eines Targets aus diesem Projektfile ausgeführt. Danach wird das Target JustAnotherTarget ausgeführt bevor das eigentlich gewollte, SimpleTarget gestartet wird.
MSBuild 2.0 konnte also bereits Abhängigkeiten zwischen Targets definieren, jedoch besteht dann eine feste Bindung zwischen den Targets
Die Folge davon ist, dass die Wiederverwendbarkeit des eigentlichen Targets geringer wird, da es nur in Verbindung mit der eigenen Abhängigkeit verbreitet werden kann.
Before- und AfterTargets in MSBuild 4.0
In MSBuild 4.0 hat man durch BeforeTargets und AfterTargets nun die Möglichkeit den Kontrollfluss der Targets zu bearbeiten, ohne eine feste Kopplung einzelner Komponenten zu definieren.
Das oben gezeigte Script kann in MSBuild 4.0 wie folgt geschrieben werden.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="SimpleTarget"
ToolsVersion="4.0">
<Target Name="SimpleTarget">
<Message Text="This target is only for printing a message!"/>
<Message Text="STAGE DEFAULT TARGET: $(ExternalProperty)"/>
<Warning Text="FY"/>
</Target>
<Target Name="PrintWelcomeMessage"
BeforeTargets="SimpleTarget">
<Message Text="Hello! Welcome to MSBuild tutorial by http://www.dotnet-rocks.de"
Importance="high"/>
<Message Text="STAGE INITIALIZE: $(ExternalProperty)"/>
</Target>
<Target Name="JustAnotherTarget"
AfterTargets="SimpleTarget">
<Message Text="This is just another target which displays a message..."/>
<Message Text="STAGE DEFAULT TARGET DEPENDENCY: $(ExternalProperty)"/>
</Target>
</Project>
Bei der Verwendung von BeforeTargets und AfterTargets ist es irrelevant in welcher Reihenfolge die Targets im Buildscript deklariert sind, MSBuild kümmert sich darum, dass die Targets in der korrekten Reihenfolge abgearbeitet werden.
Der eigentliche Nutzen wird erst richtig sichtbar, wenn man sich das Target SimpleTarget anschaut, dieses Target könnte alternativ aus einem Shared-Target-File kommen, dennoch würde MSBuild zunächst das Targets PrintWelcomeMessage ausführen. Dadurch kann sichergestellt werden, das Targets, die Kernlogik enthalten wiederverwendbar sind, ohne deren Pre- bzw. Post-Target mitliefern zu müssen.
Sowohl für Before- als auch für After-Targets können beliebig viele Targets durch Semikolon (;) getrennt, angegeben werden.
Fazit
BeforeTargets und AfterTargets erlauben es dem Entwickler schnell ein Preset an atomaren Targets zu erstellen, ohne den Ablaufplan des eigentlichen Buildfiles vorzugeben. Somit können in Version 4.0 auch beim Erstellen von Buildfiles etwas mehr auf die DRY Konventionen geachtet werden, dar einzelne Targets nun besser abstrahiert werden können.
Technorati-Tags:
MSBuild,
MSBuild 4.0