DEV Community

Jimmy
Jimmy

Posted on • Edited on

4 2

Nested builders with Action<T>

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();

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (2)

Collapse
 
paulvanbladel profile image
paul van bladel • Edited

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.

public PersonBuilder AddChild(Action<PersonBuilder> builder)
        {
            var personBuilder = new PersonBuilder();
            builder.Invoke(personBuilder); // instead of builder(personBuilder)

            _person.Children.Add(personBuilder.Build());

            return this;
        }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
paulvanbladel profile image
paul van bladel • Edited

Very Elegant, thanks for sharing.
Small bug, you need to initialize the Children List:

    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public List<Person> Children { get; set; } 
                 = new();
    }
Enter fullscreen mode Exit fullscreen mode

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay