Builder design pattern for objects with nested properties
Tags: csharp, productivity, dotnet, designpatterns
Published: 2019-04-13 17:04:16

---
title: Builder design pattern for objects with nested properties 
published: true
description: How to keep the beauty of the builder design pattern for objects with nested properties 
tags: csharp, productivity, dotnet ,designpatterns 
cover_image: https://thepracticaldev.s3.amazonaws.com/i/zi5x1bcnn0rk9ny5pb5j.jpeg
---
A typical [builder design pattern](https://en.wikipedia.org/wiki/Builder_pattern) is suitable for a one-dimensional domain object like this 

```c#
public class Data
{
    public string Id { get; set; }
    public DateTime DateTime { get; set; }
}
```
and its corresponding builder class will be as follows 

```c#
public class DataBuilder
{
    private readonly Data _data;

    public DataBuilder()
    {
        _data = new Data();
    }

    public DataBuilder Id(string id)
    {
        this._data.Id = id;
        return this;
    }

    public DataBuilder Datetime(DateTime dateTime)
    {
        this._data.DateTime = dateTime; 
        return this;
    }

    public string Build()
    {
        return $"id: {_data.Id}  date:{_data.DateTime}";
    }
}
```
so it can be used like this 
```c#
var result = new DataBuilder()
            .Id("11")
            .Datetime(DateTime.Now)
            .Build();
```

but what if our domain object consist of other domain objects like this 
```c#
public class Data
{
    public string Id { get; set; }
    public DateTime DateTime { get; set; }
    public Nested Nested { get; set; }
}

public class Nested
{
    public string Name { get; set; }
    public string Surname { get; set; }
}
```
in this case the beauty of the usage of the builder pattern will be somehow compromised
```c#
var nested = new Nested()
{
    Name="Ali",
    Surname="Tabryzy"
};

var result = new DataBuilder()
    .Id("11")
    .Nested(nested)
    .Datetime(DateTime.Now)
    .Build();
```  
In order to keep the beauty of the builder pattern we can implement it like this 
```c#
public class DataBuilder
{
    private readonly Data _data;
    public readonly NestedBuilder Nested;
    private Nested _nested;

    public class NestedBuilder
    {
        private readonly DataBuilder _dataBuilder;

        public NestedBuilder(DataBuilder dataBuilder)
        {
            _dataBuilder = dataBuilder;
        }

        public DataBuilder Name(string name)
        {
            if (_dataBuilder._nested == null)
                _dataBuilder._nested = new Nested();
            _dataBuilder._nested.Name = name;
            return _dataBuilder;
        }

        public DataBuilder Surname(string surname)
        {
            if (_dataBuilder._nested == null)
                _dataBuilder._nested = new Nested();
            _dataBuilder._nested.Surname = surname;
            return _dataBuilder;
        }
    }

    public DataBuilder()
    {
        _data = new Data();
        Nested = new NestedBuilder(this);
    }


    public DataBuilder Datetime(DateTime dateTime)
    {
        this._data.DateTime = dateTime; 
        return this;
    }
    public DataBuilder Id(string id)
    {
        this._data.Id = id;
        return this;
    }

    public string Build()
    {
        return $"id: {_data.Id} name:" + 
            $"{_nested.Name} surname: {_nested.Surname} date:{_data.DateTime}";
    }
}
```
which the usage will be as beautiful as it is for a one-dimensional domain object as follows
```c#
var result = new DataBuilder()
    .Id("11")
    .Nested.Name("ali")
    .Nested.Surname("Tabryzy")
    .Datetime(DateTime.Now)
    .Build();
``` 

Happy coding :)