Immutable Builder Design Pattern In C#

Immutable Builder Design Pattern

In the previous blog, we explored the Fluent Builder Design Pattern, including:

  • Product
  • Builder interface that declares fluent behaviour
  • Concrete Builder in which each SET returns the builder itself
  • Chaining of the calls of SETs from client code

We learned how the Fluent Builder Pattern helps solve the traditional builder design pattern issue of many lines of code and hard mantainablity.

Before continuing this blog, I recomment to read the previous blog by clicking here


Immutable Builder Pattern

One major improvement to the traditional Builder Pattern is immutability. 

An immutable object is an object whose state cannot change after it is created. 

This makes programs safer because: 

  • No accidental modifications 
  • Better thread safety 
  • More predictable behavior 

Immutable Product 

Instead of allowing properties to be modified, we make them read-only. So let’s modify the User Class

public class User 
{ 
   public string Name { get; } //readonly
   public string Email { get; } //readonly 
   public string Phone { get; }  //readonly
   public string Address { get; }  //readonly
   public int Age { get; } //readonly
 
   public User(string name, string email, string phone, string address, int age) 
   { 
       Name = name; // set once
       Email = email; // set once 
       Phone = phone;  // set once
       Address = address;  // set once
       Age = age; // set once
   } 
}

Notice there are no setters. 

Values will be assigned once object is created.

Once the object is created, its values cannot change. 

Immutable Builder 

The builder collects values temporarily and creates the immutable object only when Build() is called. 

public class ImmutableUserBuilder 
{ 
   private string _name; // collector
   private string _email; // collector
   private string _phone; // collector
   private string _address; // collector
   private int _age; // collector
 
   public ImmutableUserBuilder SetName(string name) 
   { 
       _name = name; // sets once
       return this; 
   } 
 
   public ImmutableUserBuilder SetEmail(string email) 
   { 
       _email = email; // sets once
       return this; 
   } 
 
   public ImmutableUserBuilder SetPhone(string phone) 
   { 
       _phone = phone; // sets once
       return this; 
   } 
 
   public ImmutableUserBuilder SetAddress(string address) 
   { 
       _address = address; // sets once
       return this; 
   } 
 
   public ImmutableUserBuilder SetAge(int age) 
   { 
       _age = age; // sets once
       return this; 
   } 
 
   public User Build() 
   { 
      // passes collected values to the constructor and make them read only
       return new User(_name, _email, _phone, _address, _age); 
   } 
}

Usage: 

var user = new ImmutableUserBuilder() 
           .SetName("Avinash") 
           .SetEmail("xyz@abc.com") 
           .SetAge(30) 
           .Build()

Now the created User object cannot be modified. 

When to Use an Immutable Builder

Use an Immutable Builder when the final object must be immutable (cannot change after creation).

  • When the object must be thread-safe – Immutable objects are naturally thread-safe because their state never changes. Like Configuration objects, System settings, DTOs shared across threads etc.
  • When you want to prevent accidental modification – In large systems objects often travel across layers. If they are mutable, someone might change them unintentionally.
  • When the object represents a fixed state – When the object represents a fixed state
  • When you want functional-style design – Immutable builders fit well with – Functional programming, Event-driven architecture, Domain-driven design

When NOT to Use an Immutable Builder

  • When the object changes frequently 
  • When performance is critical and objects are created very frequently 
  • The object needs frequent state changes. 

That’s it for the blog, In the next blog we will study about Step Builder Pattern. To read the blog click here

Thanks for reading

Read more here

Recommended Topics

Popular Tags

.net .Net Core .NET Developers .NET Development Future .NET Productivity .NET programming agentic ai AI Agents AI Tools .NET app.Map Azure AI Boilerplate Builder Design Pattern in C# C# C# AI C# Design Patterns C# Programming circuit breaker pattern Code Assistants Coding Coding best practices Coding in AI Creational Design Patterns Design Patterns Design Patterns in C# dotnet core resilience Factory Design Patterns in C# Fluent Builder Design Pattern Generative AI Immutable Builder Design Pattern In C# Knowledge Lightweight API LLMs .NET Machine Learning .NET MapGet Microservices microservices resilience ML.NET Motivational polly v8 resilience architecture REST API retry pattern Semantic Kernel Singleton Design Pattern in C# Software Architecture Step Builder Design Pattern In C# The Avinash Joshi TheAvinashJoshi Top 5 AI tools trending coding methods vibe coding Visual Studio AI Web API Web Development