A Roslyn source generator that creates fluent Builder classes for your records and immutable types.
No runtime dependencies. Fully AOT-compatible. Zero reflection.
dotnet add package BuilderGenMark any record, class, or struct with [GenerateBuilder]:
using BuilderGen;
[GenerateBuilder]
public record Order(string CustomerId, List<LineItem> Items, decimal Discount = 0);
[GenerateBuilder]
public record LineItem(string Sku, int Quantity);A fluent builder is generated automatically:
var order = new OrderBuilder()
.WithCustomerId("C123")
.AddItem(new LineItem("SKU1", 2))
.WithDiscount(0.1m)
.Build();Every constructor parameter gets a With{Name}() method that returns the builder for chaining.
var person = new PersonBuilder()
.WithFirstName("Alice")
.WithLastName("Smith")
.WithAge(30)
.Build();Properties without default values are required. Build() throws InvalidOperationException with a clear message if any required property is missing:
var builder = new PersonBuilder()
.WithFirstName("Alice");
// LastName not set!
builder.Build(); // throws: "The following required properties were not set: LastName"Parameters with default values are optional — you can omit them:
[GenerateBuilder]
public record Order(string CustomerId, decimal Discount = 0);
var order = new OrderBuilder()
.WithCustomerId("C123")
.Build(); // Discount defaults to 0For List<T>, IList<T>, IEnumerable<T>, ICollection<T>, IReadOnlyList<T>, and IReadOnlyCollection<T> properties, both With{Name}() and Add{SingularName}() methods are generated:
var cart = new ShoppingCartBuilder()
.WithOwner("Alice")
.AddItem("Apple")
.AddItem("Banana")
.Build();If a property's type also has [GenerateBuilder], a Configure{Name}() method is generated:
[GenerateBuilder]
public record Address(string Street, string City);
[GenerateBuilder]
public record Person(string Name, Address HomeAddress);
var person = new PersonBuilder()
.WithName("Alice")
.ConfigureHomeAddress(a => a
.WithStreet("123 Main St")
.WithCity("Springfield"))
.Build();- Records (
record,record struct) - Classes (with explicit constructors)
- Structs (with explicit constructors)
BuilderGen is a Roslyn incremental source generator. At compile time it:
- Finds types marked with
[GenerateBuilder] - Extracts constructor parameters via the semantic model
- Emits a
{TypeName}Builderclass in the same namespace
No runtime code is shipped — the generator runs only during compilation.
| Attribute | Target | Effect |
|---|---|---|
[GenerateBuilder] |
class, record, struct | Generates a {TypeName}Builder class |
| Member | Description |
|---|---|
With{Property}(T value) |
Sets the property value, returns builder |
Add{Singular}(T item) |
Adds to collection property, returns builder |
Configure{Property}(Action<TBuilder>) |
Configures nested builder type, returns builder |
Build() |
Creates the target instance, validates required properties |
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Run
dotnet testto verify - Submit a pull request
MIT