|
| 1 | +# JD.MSBuild.Fluent Documentation |
| 2 | + |
| 3 | +Welcome to the comprehensive documentation for **JD.MSBuild.Fluent**, a strongly-typed fluent DSL for authoring MSBuild `.props`, `.targets`, and SDK assets with the ergonomics of modern C#. |
| 4 | + |
| 5 | +## What is JD.MSBuild.Fluent? |
| 6 | + |
| 7 | +JD.MSBuild.Fluent is a library that transforms MSBuild package authoring from error-prone XML manipulation into type-safe, refactorable C# code. Define your MSBuild packages using intuitive fluent APIs, then emit them into the exact NuGet folder layout (`build/`, `buildTransitive/`, `Sdk/`) expected by MSBuild and NuGet. |
| 8 | + |
| 9 | +### Key Features |
| 10 | + |
| 11 | +- **Strongly-Typed DSL**: Author MSBuild constructs with IntelliSense, compile-time checking, and refactoring support |
| 12 | +- **Fluent API**: Chain method calls naturally to build complex package definitions |
| 13 | +- **100% Standard MSBuild**: Generates canonical, deterministic MSBuild XML that works everywhere |
| 14 | +- **Intermediate Representation**: Composable IR layer separates authoring from rendering |
| 15 | +- **Deterministic Output**: Canonical ordering of properties, items, and task parameters for meaningful diffs |
| 16 | +- **Multi-Target Support**: Build packages targeting multiple frameworks or platforms |
| 17 | +- **SDK-Style Packages**: Full support for MSBuild SDK-style project imports |
| 18 | +- **Type-Safety Options**: Optional strongly-typed property, target, and item names |
| 19 | + |
| 20 | +## Quick Example |
| 21 | + |
| 22 | +```csharp |
| 23 | +using JD.MSBuild.Fluent; |
| 24 | +using JD.MSBuild.Fluent.Fluent; |
| 25 | + |
| 26 | +var package = Package.Define("MyCompany.Build") |
| 27 | + .Description("Custom build tasks for MyCompany projects") |
| 28 | + .Props(p => p |
| 29 | + .Property("MyCompanyBuildEnabled", "true") |
| 30 | + .Property("MyCompanyVersion", "2.0.0")) |
| 31 | + .Targets(t => t |
| 32 | + .Target("MyCompany_PreBuild", target => target |
| 33 | + .BeforeTargets("Build") |
| 34 | + .Condition("'$(MyCompanyBuildEnabled)' == 'true'") |
| 35 | + .Message("MyCompany Build v$(MyCompanyVersion)", "High"))) |
| 36 | + .Pack(o => o.BuildTransitive = true) |
| 37 | + .Build(); |
| 38 | +``` |
| 39 | + |
| 40 | +This generates clean MSBuild XML ready for packaging: |
| 41 | + |
| 42 | +```xml |
| 43 | +<Project> |
| 44 | + <PropertyGroup> |
| 45 | + <MyCompanyBuildEnabled>true</MyCompanyBuildEnabled> |
| 46 | + <MyCompanyVersion>2.0.0</MyCompanyVersion> |
| 47 | + </PropertyGroup> |
| 48 | +</Project> |
| 49 | +``` |
| 50 | + |
| 51 | +## Why Use JD.MSBuild.Fluent? |
| 52 | + |
| 53 | +### Traditional XML Authoring Challenges |
| 54 | + |
| 55 | +Authoring MSBuild packages manually involves: |
| 56 | + |
| 57 | +- **No IntelliSense**: Easy to mistype property names, target names, or task parameters |
| 58 | +- **No Refactoring**: Renaming requires manual find-and-replace across multiple files |
| 59 | +- **Verbose Syntax**: XML is repetitive and hard to scan |
| 60 | +- **No Reusability**: Difficult to extract common patterns into reusable functions |
| 61 | +- **Merge Conflicts**: XML diffs are noisy and hard to resolve |
| 62 | +- **Late Errors**: Typos and structural errors only appear at build time |
| 63 | + |
| 64 | +### The JD.MSBuild.Fluent Approach |
| 65 | + |
| 66 | +JD.MSBuild.Fluent treats MSBuild authoring as a first-class C# development experience: |
| 67 | + |
| 68 | +- **Full IntelliSense**: Discover available methods and properties as you type |
| 69 | +- **Compile-Time Safety**: Catch structural errors before generating any XML |
| 70 | +- **Easy Refactoring**: Use IDE refactoring tools to rename properties, targets, and methods |
| 71 | +- **DRY Principles**: Extract helper methods, share configurations, compose definitions |
| 72 | +- **Clean Diffs**: Generated XML has canonical ordering for meaningful version control |
| 73 | +- **Early Validation**: Validation rules run during build, before MSBuild sees the output |
| 74 | + |
| 75 | +## Architecture Overview |
| 76 | + |
| 77 | +JD.MSBuild.Fluent has a layered architecture: |
| 78 | + |
| 79 | +``` |
| 80 | +┌─────────────────────────────────────┐ |
| 81 | +│ Fluent API (Builders) │ ← You work here |
| 82 | +│ Package.Define(...).Props().Build()│ |
| 83 | +├─────────────────────────────────────┤ |
| 84 | +│ Intermediate Representation (IR) │ ← Composable data structures |
| 85 | +│ MsBuildProject, MsBuildTarget │ |
| 86 | +├─────────────────────────────────────┤ |
| 87 | +│ XML Renderer │ ← Deterministic serialization |
| 88 | +│ MsBuildXmlRenderer │ |
| 89 | +├─────────────────────────────────────┤ |
| 90 | +│ Package Emitter │ ← NuGet folder layout |
| 91 | +│ build/, buildTransitive/, Sdk/ │ |
| 92 | +└─────────────────────────────────────┘ |
| 93 | +``` |
| 94 | + |
| 95 | +### Layers Explained |
| 96 | + |
| 97 | +1. **Fluent API**: High-level builders (`Package`, `PropsBuilder`, `TargetsBuilder`) for natural C# authoring |
| 98 | +2. **IR Layer**: Immutable data structures (`MsBuildProject`, `MsBuildTarget`, `MsBuildProperty`) representing MSBuild constructs |
| 99 | +3. **Renderer**: Converts IR to canonical MSBuild XML with deterministic ordering |
| 100 | +4. **Emitter**: Organizes rendered XML into NuGet package folder structure |
| 101 | + |
| 102 | +## Getting Started |
| 103 | + |
| 104 | +<div class="embeddedContent"> |
| 105 | + <a href="user-guides/getting-started/installation.html" class="xref">Installation Guide</a> |
| 106 | +</div> |
| 107 | + |
| 108 | +<div class="embeddedContent"> |
| 109 | + <a href="user-guides/getting-started/first-package.html" class="xref">Create Your First Package</a> |
| 110 | +</div> |
| 111 | + |
| 112 | +<div class="embeddedContent"> |
| 113 | + <a href="user-guides/getting-started/quick-start.html" class="xref">Quick Start</a> |
| 114 | +</div> |
| 115 | + |
| 116 | +## Core Concepts |
| 117 | + |
| 118 | +<div class="embeddedContent"> |
| 119 | + <a href="user-guides/core-concepts/architecture.html" class="xref">Architecture & Design</a> |
| 120 | +</div> |
| 121 | + |
| 122 | +<div class="embeddedContent"> |
| 123 | + <a href="user-guides/core-concepts/ir.html" class="xref">Intermediate Representation (IR)</a> |
| 124 | +</div> |
| 125 | + |
| 126 | +<div class="embeddedContent"> |
| 127 | + <a href="user-guides/core-concepts/package-structure.html" class="xref">Package Structure</a> |
| 128 | +</div> |
| 129 | + |
| 130 | +## User Guides |
| 131 | + |
| 132 | +### Properties, Items & Metadata |
| 133 | +- [Working with Properties](user-guides/properties-items/properties.md) |
| 134 | +- [Working with Items](user-guides/properties-items/items.md) |
| 135 | +- [Item Metadata](user-guides/properties-items/metadata.md) |
| 136 | +- [Conditional Logic](user-guides/properties-items/conditionals.md) |
| 137 | + |
| 138 | +### Targets & Tasks |
| 139 | +- [Target Orchestration](user-guides/targets-tasks/orchestration.md) |
| 140 | +- [Built-in Tasks Reference](user-guides/targets-tasks/builtin-tasks.md) |
| 141 | +- [Task Outputs](user-guides/targets-tasks/task-outputs.md) |
| 142 | + |
| 143 | +### Advanced Topics |
| 144 | +- [UsingTask Declarations](user-guides/advanced/usingtask.md) |
| 145 | +- [Multi-Target Framework Patterns](user-guides/advanced/multi-tfm.md) |
| 146 | +- [Choose/When/Otherwise](user-guides/advanced/choose.md) |
| 147 | +- [Import Statements](user-guides/advanced/imports.md) |
| 148 | +- [Strongly-Typed Helpers](user-guides/advanced/strongly-typed.md) |
| 149 | + |
| 150 | +## CLI Reference |
| 151 | + |
| 152 | +<div class="embeddedContent"> |
| 153 | + <a href="user-guides/cli/index.html" class="xref">Command-Line Interface</a> |
| 154 | +</div> |
| 155 | + |
| 156 | +## API Reference |
| 157 | + |
| 158 | +Browse the complete API documentation: |
| 159 | + |
| 160 | +<div class="embeddedContent"> |
| 161 | + <a href="api/index.html" class="xref">API Reference</a> |
| 162 | +</div> |
| 163 | + |
| 164 | +## Troubleshooting |
| 165 | + |
| 166 | +<div class="embeddedContent"> |
| 167 | + <a href="user-guides/troubleshooting/index.html" class="xref">Troubleshooting Guide</a> |
| 168 | +</div> |
| 169 | + |
| 170 | +## Samples |
| 171 | + |
| 172 | +Explore working examples in the repository: |
| 173 | + |
| 174 | +- **MinimalSdkPackage**: A complete end-to-end SDK-style package definition |
| 175 | +- **ContosoSDK**: Comprehensive example demonstrating advanced patterns |
| 176 | + |
| 177 | +## Contributing |
| 178 | + |
| 179 | +Contributions are welcome! See the repository's CONTRIBUTING.md for guidelines on: |
| 180 | + |
| 181 | +- Reporting bugs |
| 182 | +- Proposing features |
| 183 | +- Submitting pull requests |
| 184 | +- Code style and conventions |
| 185 | + |
| 186 | +## License |
| 187 | + |
| 188 | +JD.MSBuild.Fluent is licensed under the MIT License. See LICENSE in the repository root for details. |
| 189 | + |
| 190 | +## Additional Resources |
| 191 | + |
| 192 | +- [MSBuild Concepts (Microsoft Docs)](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-concepts) |
| 193 | +- [NuGet Package Authoring](https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package-msbuild) |
| 194 | +- [MSBuild SDK Resolver](https://learn.microsoft.com/en-us/visualstudio/msbuild/how-to-use-project-sdk) |
| 195 | +- [MSBuild Reserved and Well-Known Properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties) |
0 commit comments