Membandingkan properti dan item
Properti dan item MSBuild keduanya digunakan untuk meneruskan informasi ke tugas, mengevaluasi kondisi, dan menyimpan nilai yang dapat dirujuk di seluruh file proyek.
Properti adalah pasangan nama-nilai. Untuk informasi selengkapnya, lihat properti MSBuild.
Item adalah objek yang biasanya mewakili file. Objek item dapat memiliki koleksi metadata terkait. Metadata adalah pasangan nama-nilai. Untuk informasi selengkapnya, lihat Item.
Skalar dan vektor
Karena properti MSBuild adalah pasangan nama-nilai yang hanya memiliki satu nilai string, properti tersebut sering digambarkan sebagai skalar. Karena tipe item MSBuild adalah daftar item, item tersebut sering digambarkan sebagai vektor. Namun, dalam praktiknya, properti dapat mewakili beberapa nilai, dan tipe item dapat memiliki nol atau satu item.
Injeksi dependensi target
Untuk melihat bagaimana properti dapat mewakili beberapa nilai, pertimbangkan pola penggunaan umum untuk menambahkan target ke daftar target yang akan dibangun. Daftar ini biasanya diwakili oleh nilai properti, dengan nama target dipisahkan oleh titik koma.
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
Properti BuildDependsOn
biasanya digunakan sebagai argumen atribut target DependsOnTargets
, secara efektif mengonversinya menjadi daftar item. Properti ini dapat diganti untuk menambahkan target atau mengubah urutan eksekusi target. Contohnya,
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
CustomBuild;
</BuildDependsOn>
</PropertyGroup>
menambahkan target CustomBuild ke daftar target, memberikan BuildDependsOn
nilai BeforeBuild;CoreBuild;AfterBuild;CustomBuild
.
Dimulai dengan MSBuild 4.0, injeksi dependensi target tidak digunakan lagi. Gunakan atribut AfterTargets
dan BeforeTargets
sebagai gantinya. Untuk informasi selengkapnya, lihat Urutan build target.
Konversi antara string dan daftar item
MSBuild melakukan konversi ke dan dari tipe item dan nilai string sesuai kebutuhan. Untuk melihat bagaimana daftar item bisa menjadi nilai string, pertimbangkan apa yang terjadi saat tipe item digunakan sebagai nilai properti MSBuild:
<ItemGroup>
<OutputDir Include="KeyFiles\;Certificates\" />
</ItemGroup>
<PropertyGroup>
<OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>
Tipe item OutputDir memiliki atribut Include
dengan nilai "KeyFiles\;Certificates\". MSBuild mengurai string ini menjadi dua item: KeyFiles\ and Certificates\. Ketika tipe item OutputDir digunakan sebagai nilai properti OutputDirList, MSBuild mengonversi atau "meratakan" tipe item ke string yang dipisahkan titik koma "KeyFiles\;Certificates\".
Properti dan item dalam tugas
Properti dan item digunakan sebagai input dan output untuk tugas MSBuild. Untuk informasi selengkapnya, lihat Tugas.
Properti diteruskan ke tugas sebagai atribut. Dalam tugas, properti MSBuild diwakili oleh jenis properti yang nilainya dapat dikonversi ke dan dari string. Jenis properti yang didukung meliputi bool
, char
, DateTime
, Decimal
, Double
, int
, string
, dan jenis apa pun yang ChangeType dapat menangani.
Item diteruskan ke tugas sebagai ITaskItem objek. Dalam tugas, ItemSpec mewakili nilai item dan GetMetadata mengambil metadatanya.
Daftar item tipe item dapat diteruskan sebagai array ITaskItem
objek. Dimulai dengan .NET Framework 3.5, item dapat dihapus dari daftar item dalam target dengan menggunakan atribut Remove
. Karena item dapat dihapus dari daftar item, dimungkinkan bagi tipe item untuk memiliki item nol. Jika daftar item diteruskan ke tugas, kode dalam tugas harus memeriksa kemungkinan ini.
Urutan evaluasi properti dan item
Selama fase evaluasi build, file yang diimpor dimasukkan ke dalam build dalam urutan kemunculannya. Properti dan item didefinisikan dalam tiga lintasan dalam urutan berikut:
Properti didefinisikan dan dimodifikasi dalam urutan kemunculannya.
Definisi item didefinisikan dan dimodifikasi dalam urutan kemunculannya.
Item didefinisikan dan dimodifikasi dalam urutan kemunculannya.
Selama fase eksekusi build, properti, dan item yang ditentukan dalam target dievaluasi bersama-sama dalam satu fase dalam urutan kemunculannya.
Namun, ini bukan cerita lengkapnya. Saat properti, definisi item, atau item ditentukan, nilainya dievaluasi. Evaluator ekspresi memperluas string yang menentukan nilai. Ekspansi string tergantung pada fase build. Berikut adalah urutan evaluasi properti dan item yang lebih rinci:
Selama fase evaluasi build:
Properti didefinisikan dan dimodifikasi dalam urutan kemunculannya. Fungsi properti dijalankan. Nilai properti dalam formulir $(PropertyName) diperluas dalam ekspresi. Nilai properti diatur ke ekspresi yang diperluas.
Definisi item didefinisikan dan dimodifikasi dalam urutan kemunculannya. Fungsi properti telah diperluas dalam ekspresi. Nilai metadata diatur ke ekspresi yang diperluas.
Tipe item ditentukan dan dimodifikasi dalam urutan kemunculannya. Nilai item dalam formulir @(ItemType) diperluas. Transformasi item juga diperluas. Fungsi dan nilai properti telah diperluas dalam ekspresi. Daftar item dan nilai metadata diatur ke ekspresi yang diperluas.
Selama fase eksekusi build:
- Properti dan item yang ditentukan dalam target dievaluasi bersama-sama dalam urutan kemunculannya. Fungsi properti dijalankan dan nilai properti diperluas dalam ekspresi. Nilai item dan transformasi item juga diperluas. Nilai properti, nilai tipe item, dan nilai metadata diatur ke ekspresi yang diperluas.
Efek halus dari urutan evaluasi
Dalam fase evaluasi build, evaluasi properti mendahului evaluasi item. Namun demikian, properti dapat memiliki nilai yang tampaknya bergantung pada nilai item. Pertimbangkan skrip berikut.
<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>
Menjalankan tugas Pesan menampilkan pesan ini:
KeyFileVersion: 1.0.0.3
Ini karena nilai KeyFileVersion
sebenarnya adalah string "@(KeyFile->'%(Version)')". Transformasi item dan item tidak diperluas saat properti pertama kali ditentukan, sehingga KeyFileVersion
properti diberi nilai string yang tidak terlampir.
Selama fase eksekusi build, ketika memproses tugas Pesan, MSBuild memperluas string "@(KeyFile->'%(Version)')" untuk menghasilkan "1.0.0.3".
Perhatikan bahwa pesan yang sama akan muncul meskipun properti dan grup item dibalik secara berurutan.
Sebagai contoh kedua, pertimbangkan apa yang dapat terjadi ketika grup properti dan item berada dalam target:
<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>
Tugas Pesan menampilkan pesan ini:
KeyFileVersion:
Ini karena selama fase eksekusi grup build, properti, dan item yang ditentukan dalam target dievaluasi dari atas ke bawah secara bersamaan. Ketika KeyFileVersion
ditentukan, KeyFile
tidak diketahui. Oleh karena itu, transformasi item diperluas ke string kosong.
Dalam kasus ini, membalik urutan grup properti dan item akan memulihkan pesan asli:
<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>
Nilai KeyFileVersion
diatur ke "1.0.0.3" dan bukan ke "@(KeyFile->'%(Version)')". Tugas Pesan menampilkan pesan ini:
KeyFileVersion: 1.0.0.3