JD.MSBuild.Fluent
A strongly-typed, fluent DSL for authoring MSBuild packages in C#
Author MSBuild .props, .targets, and SDK assets using a strongly-typed fluent API in C#, then automatically generate 100% standard MSBuild XML during build. No more hand-editing XML - write refactorable, testable, type-safe C# code instead.
โจ Features
- ๐ฏ Strongly-typed fluent API - IntelliSense, refactoring, compile-time validation
- ๐ Automatic build integration - Generate MSBuild assets during
dotnet build, no CLI required - ๐ฆ Full NuGet layout support -
build/,buildTransitive/, andSdk/folders - ๐ง XML scaffolding - Convert existing XML to fluent code with
jdmsbuild scaffold - โ Production-tested - Validated against real-world MSBuild packages
- ๐ Deterministic output - Consistent XML generation for meaningful diffs
Quick Start
1. Install the package
<PackageReference Include="JD.MSBuild.Fluent" Version="*" />
2. Define your MSBuild assets in C#
using JD.MSBuild.Fluent;
using JD.MSBuild.Fluent.Fluent;
namespace MySdk;
public static class DefinitionFactory
{
public static PackageDefinition Create() => Package.Define("MySdk")
.Props(p => p
.Property("MySdkEnabled", "true")
.Property("MySdkVersion", "1.0.0"))
.Targets(t => t
.Target("MySdk_Hello", target => target
.BeforeTargets("Build")
.Condition("'$(MySdkEnabled)' == 'true'")
.Message("Hello from MySdk v$(MySdkVersion)!", "High")))
.Pack(o => {
o.BuildTransitive = true;
o.EmitSdk = true;
})
.Build();
}
3. Build your project
MSBuild assets are automatically generated during build and packaged correctly:
- โ
build/MySdk.props - โ
build/MySdk.targets - โ
buildTransitive/MySdk.propsand.targets - โ
Sdk/MySdk/Sdk.propsandSdk.targets
No CLI required! Just build and pack:
dotnet build
dotnet pack
๐ฏ Why JD.MSBuild.Fluent?
Problem: Hand-editing MSBuild XML is painful
- โ No IntelliSense or type safety
- โ No refactoring support
- โ Hard to test and validate
- โ Copy-paste leads to duplication
- โ Difficult to review diffs
Solution: Write C# instead
- โ Strongly-typed API with full IntelliSense
- โ Refactoring support - rename, extract, move
- โ Unit testable - validate logic before publishing
- โ DRY principle - reuse patterns across targets
- โ Better diffs - meaningful C# changes instead of XML noise
- โ Automatic generation - integrated into build pipeline
๐ Documentation
Getting Started
- Introduction - Project overview and core concepts
- Getting Started Guide - Installation and your first package
- Examples - Real-world usage examples
User Guides
- Overview - Guide to all user documentation
- Basic Concepts - Understanding the fluent API
- MSBuild Integration - How build integration works
- Migration from XML - Convert existing XML to fluent
- Advanced Topics - Custom tasks, conditions, and more
Reference
- API Reference - Complete API documentation
- CLI Reference - Command-line tool documentation
๐ Migrate from XML
Convert existing MSBuild XML files to fluent API:
# Install CLI tool
dotnet tool install -g JD.MSBuild.Fluent.Cli
# Scaffold from existing XML
jdmsbuild scaffold --xml MyPackage.targets --output DefinitionFactory.cs --package-id MyCompany.MyPackage
See the Migration Guide for complete details.
๐งช Samples
- Minimal SDK Package - Complete end-to-end example
- Integration tests validate against JD.Efcpt.Build (real-world production package)
๐๏ธ Architecture Overview
JD.MSBuild.Fluent has a clean, layered architecture:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Fluent API (Builders) โ โ You work here
โ Package.Define(...).Props().Build()โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Intermediate Representation (IR) โ โ Composable data structures
โ MsBuildProject, MsBuildTarget โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ XML Renderer โ โ Deterministic serialization
โ MsBuildXmlRenderer โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Package Emitter โ โ NuGet folder layout
โ build/, buildTransitive/, Sdk/ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Layers Explained
- Fluent API: High-level builders for natural C# authoring
- IR Layer: Immutable data structures representing MSBuild constructs
- Renderer: Converts IR to canonical MSBuild XML with deterministic ordering
- Emitter: Organizes rendered XML into NuGet package folder structure
๐ค Contributing
Contributions welcome! See our GitHub repository to get started.
๐ License
๐ Related Projects
- JD.Efcpt.Build - EF Core Power Tools build integration
- JD.MSBuild.Containers - Docker container build integration