--- name: item-management description: "Own concrete MSBuild ItemGroup and item-expression questions. USE FOR: Include, Remove, Update, item identity and metadata, transforms, filtering, batching, duplicate or overlapping items, and reviews that verify whether those operations are correct. Generated items stay in scope when the central defect is item identity, metadata, batching, duplicate declarations, or glob/Remove/Update semantics. For a generated artifact missing from compilation or output, wrong target timing/path, or FileWrites clean tracking without a broader item-semantics defect, use including-generated-files. The item operation may be broken, suspected, or already correct. Exclude property-only issues, general incrementality with no item question, broad reviews with no concrete item concern, and non-MSBuild systems." license: MIT --- # MSBuild Item Management Patterns Canonical patterns for working with item groups, from `Microsoft.Common.CurrentVersion.targets`. ## Include / Remove / Update — Three Operations | Operation | Purpose | When to use | |---|---|---| | `Include` | Add new items to the group | Creating items with identity + metadata | | `Remove` | Remove items matching a pattern | Excluding files or clearing a group | | `Update` | Modify metadata on existing items | Adding/changing metadata without re-adding | ### Include — Add Items ```xml true ``` ### Remove — Subtract Items ```xml <_CleanOrphanFileWrites Include="@(_CleanPriorFileWrites)" Exclude="@(_CleanCurrentFileWrites)" /> <_Temporary Remove="@(_Temporary)" /> ``` ### Update — Modify Existing Items ```xml true Microsoft.CodeAnalysis.Collections.SR ``` `Update` does not add items — it only modifies items already in the group. ## Item Batching — %(Metadata) When `%(Metadata)` appears in target attributes or task parameters, MSBuild **batches** execution per unique metadata value. ### Target-level batching (Outputs) ```xml ``` ### Task-level batching ```xml ``` ### Per-item filtering with Condition ```xml <_ResxOutput Include="@(EmbeddedResource->'%(OutputResource)')" Condition="'%(EmbeddedResource.WithCulture)' == 'false'" /> ``` ### Batching rules - `%(Metadata)` in `Condition` or `Outputs` → target batches per unique value. - `%(Metadata)` in task parameters → task batches per unique value. - **Do not mix `%()` from different item groups** in the same expression — this causes a cross-product (see Common Pitfalls). ## Item Transforms — @(Item->'expression') Transforms create new item lists by applying an expression to each item: ```xml ``` ## Exclude Pattern — Set Subtraction on Include ```xml ``` `Exclude` only works on `Include` — it cannot be used with `Update` or `Remove`. ## Conditional Item Inclusion ```xml ``` ## PrivateAssets on Tool/Analyzer Packages ```xml ``` ## Common Pitfalls ### Cross-product batching Referencing `%(Metadata)` from two different item groups creates O(N×M) executions: ```xml ``` ### Generated files in source tree Write to `$(IntermediateOutputPath)` (obj/), not the source directory. Source-tree generation pollutes version control and can cause duplicate compilation via globs. ### Missing FileWrites Every file created during a target must be added to `@(FileWrites)` for `dotnet clean` support.