Once I started to use the Builder Pattern it didn't take long until I faced more complex objects on multi levels.
My first solution to this was to add a method returning a new Builder and in that builder have a Complete method that would return my original Builder.
Sounds complex doesn't it? It sure is! Once I got beyond 2 levels of nesting the builder implementation was a real hell every time.
Then I discovered I could use Action, where T is another Builder. This made my builders easier to implement, and also easier to maintain.
Here's a code example on how it could look like:
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Person> Children { get; set }
}
public class PersonBuilder
{
private readonly Person _person;
public PersonBuilder()
{
_person = new Person();
}
public PersonBuilder Firstname(string firstname)
{
_person.Firstname = firstname;
return this;
}
public PersonBuilder Lastname(string lastname)
{
_person.Lastname = lastname;
return this;
}
public PersonBuilder AddChild(Action<PersonBuilder> builder)
{
var personBuilder = new PersonBuilder();
builder(personBuilder);
_person.Children.Add(personBuilder.Build())
return this;
}
public Person Build()
{
return _person;
}
}
var person = new PersonBuilder()
.Firstname("John")
.Lastname("Doe")
.AddChild(child => {
child.Firstname("Jane")
.Lastname("Doe")
})
.Build();
Top comments (2)
When you invoke the action delegate, it's more readable/understandable to also call the Invoke method of the action delegate.
Sorry... just a detail.
Very Elegant, thanks for sharing.
Small bug, you need to initialize the Children List: