Porównanie właściwości i elementów
Właściwości i elementy programu MSBuild są używane do przekazywania informacji do zadań, oceny warunków i przechowywania wartości, do których można odwoływać się w całym pliku projektu.
Właściwości to pary nazwa-wartość. Aby uzyskać więcej informacji, zobacz Właściwości programu MSBuild.
Elementy to obiekty, które zwykle reprezentują pliki. Obiekty elementów mogą mieć skojarzone kolekcje metadanych. Metadane to pary nazwa-wartość. Aby uzyskać więcej informacji, zobacz Elementy.
Skalarnie i wektory
Ponieważ właściwości programu MSBuild są parami name-value, które mają tylko jedną wartość ciągu, są często opisywane jako skalarne. Ponieważ typy elementów PROGRAMU MSBuild są listami elementów, są one często opisywane jako wektor. Jednak w praktyce właściwości mogą reprezentować wiele wartości, a typy elementów mogą mieć zero lub jeden element.
Wstrzykiwanie zależności docelowej
Aby zobaczyć, jak właściwości mogą reprezentować wiele wartości, rozważ wspólny wzorzec użycia, aby dodać element docelowy do listy obiektów docelowych do skompilowania. Ta lista jest zwykle reprezentowana przez wartość właściwości, z nazwami docelowymi oddzielonymi średnikami.
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
Właściwość BuildDependsOn
jest zwykle używana jako argument atrybutu docelowego DependsOnTargets
, skutecznie konwertując ją na listę elementów. Tę właściwość można zastąpić, aby dodać element docelowy lub zmienić docelową kolejność wykonywania. Przykład:
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
CustomBuild;
</BuildDependsOn>
</PropertyGroup>
Dodaje element docelowy CustomBuild do listy docelowej, podając BuildDependsOn
wartość BeforeBuild;CoreBuild;AfterBuild;CustomBuild
.
Począwszy od programu MSBuild 4.0, docelowa iniekcja zależności jest przestarzała. AfterTargets
Zamiast tego użyj atrybutów i BeforeTargets
. Aby uzyskać więcej informacji, zobacz Target build order (Kolejność kompilacji docelowej).
Konwersje między ciągami i listami elementów
Program MSBuild wykonuje konwersje na i z typów elementów i wartości ciągów zgodnie z potrzebami. Aby zobaczyć, jak lista elementów może stać się wartością ciągu, rozważ, co się stanie, gdy typ elementu jest używany jako wartość właściwości MSBuild:
<ItemGroup>
<OutputDir Include="KeyFiles\;Certificates\" />
</ItemGroup>
<PropertyGroup>
<OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>
Typ elementu OutputDir ma Include
atrybut o wartości "KeyFiles\; Certyfikaty\". Program MSBuild analizuje ten ciąg na dwa elementy: KeyFiles\ i Certificates\. Gdy typ elementu OutputDir jest używany jako wartość właściwości OutputDirList, MSBuild konwertuje lub "spłaszcza" typ elementu na ciąg rozdzielony średnikami "KeyFiles\; Certyfikaty\".
Właściwości i elementy w zadaniach
Właściwości i elementy są używane jako dane wejściowe i wyjściowe do zadań programu MSBuild. Aby uzyskać więcej informacji, zobacz Zadania.
Właściwości są przekazywane do zadań podrzędnych jako atrybutów. W ramach zadania właściwość MSBuild jest reprezentowana przez typ właściwości, którego wartość można przekonwertować na i z ciągu. Obsługiwane typy właściwości to bool
, , char
, DateTime
Decimal
int
Double
, string
i dowolny typ, który ChangeType może obsłużyć.
Elementy są przekazywane do zadań jako ITaskItem obiektów. W ramach zadania ItemSpec reprezentuje wartość elementu i GetMetadata pobiera jego metadane.
Listę elementów typu elementu można przekazać jako tablicę ITaskItem
obiektów. Począwszy od programu .NET Framework 3.5, elementy można usunąć z listy elementów docelowych przy użyciu atrybutu Remove
. Ponieważ elementy można usunąć z listy elementów, istnieje możliwość, że typ elementu ma zero elementów. Jeśli lista elementów jest przekazywana do zadania, kod w zadaniu powinien sprawdzić tę możliwość.
Kolejność oceny właściwości i elementów
Podczas fazy ewaluacyjnej kompilacji importowane pliki są dołączane do kompilacji w kolejności ich wyświetlania. Właściwości i elementy są definiowane w trzech przebiegach w następującej kolejności:
Właściwości są definiowane i modyfikowane w kolejności ich wyświetlania.
Definicje elementów są definiowane i modyfikowane w kolejności ich wyświetlania.
Elementy są definiowane i modyfikowane w kolejności ich wyświetlania.
W fazie wykonywania kompilacji właściwości i elementy zdefiniowane w ramach obiektów docelowych są oceniane razem w jednej fazie w kolejności, w której są wyświetlane.
Jednak nie jest to pełna historia. Po zdefiniowaniu właściwości, definicji elementu lub elementu jego wartość jest obliczana. Ewaluator wyrażeń rozszerza ciąg określający wartość. Rozszerzenie ciągu zależy od fazy kompilacji. Oto bardziej szczegółowa właściwość i kolejność oceny elementów:
W fazie oceny kompilacji:
Właściwości są definiowane i modyfikowane w kolejności ich wyświetlania. Są wykonywane funkcje właściwości. Wartości właściwości w formularzu $(PropertyName) są rozszerzane w wyrażeniach. Wartość właściwości jest ustawiona na rozwinięte wyrażenie.
Definicje elementów są definiowane i modyfikowane w kolejności ich wyświetlania. Funkcje właściwości zostały już rozwinięte w wyrażeniach. Wartości metadanych są ustawiane na rozwinięte wyrażenia.
Typy elementów są definiowane i modyfikowane w kolejności ich wyświetlania. Wartości elementów w formularzu @(ItemType) są rozwinięte. Przekształcenia elementów są również rozszerzane. Funkcje właściwości i wartości zostały już rozwinięte w wyrażeniach. Wartości listy elementów i metadanych są ustawione na rozwinięte wyrażenia.
W fazie wykonywania kompilacji:
- Właściwości i elementy zdefiniowane w elementach docelowych są oceniane razem w kolejności ich wyświetlania. Funkcje właściwości są wykonywane, a wartości właściwości są rozszerzane w wyrażeniach. Wartości elementów i przekształcenia elementów są również rozszerzane. Wartości właściwości, wartości typu elementu i wartości metadanych są ustawiane na rozwinięte wyrażenia.
Subtelne efekty kolejności oceny
W fazie oceny kompilacji ocena właściwości poprzedza ocenę elementu. Niemniej jednak właściwości mogą mieć wartości, które wydają się zależeć od wartości elementów. Rozważmy następujący skrypt.
<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>
Wykonanie zadania Komunikat powoduje wyświetlenie następującego komunikatu:
KeyFileVersion: 1.0.0.3
Jest to spowodowane tym, że wartość parametru KeyFileVersion
jest w rzeczywistości ciągiem "@(KeyFile->'%(Wersja)')". Przekształcenia elementów i elementów nie zostały rozwinięte, gdy właściwość została zdefiniowana po raz pierwszy, więc KeyFileVersion
właściwość została przypisana wartość nierozpoznanego ciągu.
W fazie wykonywania kompilacji, gdy przetwarza zadanie Komunikat, program MSBuild rozszerza ciąg "@(KeyFile->'%(Wersja)'", aby uzyskać wartość "1.0.0.3".
Zwróć uwagę, że ten sam komunikat będzie wyświetlany nawet wtedy, gdy właściwość i grupy elementów zostały odwrócone w kolejności.
W drugim przykładzie rozważ, co może się zdarzyć, gdy grupy właściwości i elementów znajdują się w ramach elementów docelowych:
<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>
Zadanie Komunikat wyświetla następujący komunikat:
KeyFileVersion:
Jest to spowodowane tym, że podczas fazy wykonywania grupy kompilacji, właściwości i elementów zdefiniowane w ramach obiektów docelowych są oceniane u góry do dołu w tym samym czasie. Gdy KeyFileVersion
parametr jest zdefiniowany, KeyFile
jest nieznany. W związku z tym przekształcenie elementu rozszerza się na pusty ciąg.
W takim przypadku odwrócenie kolejności grup właściwości i elementów powoduje przywrócenie oryginalnego komunikatu:
<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>
Wartość KeyFileVersion
elementu jest ustawiona na "1.0.0.3", a nie na "@(KeyFile->'%(Wersja)')". Zadanie Komunikat wyświetla następujący komunikat:
KeyFileVersion: 1.0.0.3