Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Aggregate Root Pattern in C#

4.91/5 (16 votes)
13 Nov 2015CPOL3 min read 69.6K  
Aggregate root pattern in C#

Aggregate root are cluster / group of objects that are treated as a single unit of data.

I am sure lots of developers are already using this pattern unknowingly, via this short note I would like to inform you formally what you are doing.

Let us try to understand the above definition with an example. Consider the below “Customer” class which has the capability to add multiple “Address” objects to it. In order to achieve the same, we have exposed an address collection from the customer class to represent the 1 to many relationships.

C#
class Customer
{
        public string CustomerName { get; set; }
        public DateTime DateofBirth { get; set; }

        public List
Addresses { get; set; } } class Address { public string Address1 { get; set; } public string Type { get; set; } }

The above class structure works perfectly well. You can create object of customer and add multiple addresses object to it.

C#
Customer cust = new Customer();
cust.CustomerName = "Shiv koirala";
cust.DateofBirth = Convert.ToDateTime("12/03/1977");

Address Address1 = new Address();
Address1.Address1 = "India";
Address1.Type = "Home";
cust.Addresses.Add(Address1);

Address Address2 = new Address();
Address2.Address1 = "Nepal";
Address2.Type = "Home";
cust.Addresses.Add(Address2);

Now let's say we want to implement the following validations:

“Customer can only have one address of Home type”.

At this moment, the address collection is a NAKED LIST COLLECTION which is exposed directly to the client. In other words, there are no validations and restrictions on the “Add” method of the list. So you can add whatever and how much ever address objects as you wish.

C#
cust.Addresses.Add(Address2);

So how to address this problem in a clean and logical way. If you think logically, “Customer” is composed of Addressescollection, so Customer is like a main root. So rather than allowing DIRECT NAKED ACCESS to Addresses list, how about accessing the address list from the customer class. In other words, centralizing access to address objects from the customer class.

So below are three steps which I have implemented to put a centralize address validation.

Step 1: I have made the address list private. So no direct access to the collection is possible.

Step 2: Created a “Add” method in the “Customer” class for adding the “Address” object. In this add method, we have put the validation that only one “Home” type address can be added.

Step 3: Clients who want to enumerate through the address collection for them we have exposed “IEnumerable” interface.

C#
class Customer
    {
	// Code removed for clarity
        private List
_Addresses; // Step 1 :- Make list private public void Add(Address obj) // Step 2 :- Address objects added via customer { int Count=0; foreach (Address t in _Addresses) { if (t.Type == "Home") { Count++; if (Count > 1) { throw new Exception("Only one home address is allowed"); } } } _Addresses.Add(obj); } public IEnumerable
Addresses // Step 3 :- To browse use enumerator { get { return _Addresses; } } }

If you analyze the above solution closely, the customer is now the root and the address object is manipulated and retrieved via the customer class.

Why did we do this? Because “Customer” and “Address” object is one logical data unit. To maintain integrity of address validation, we need to go via the “Customer” class. In the same way loading of data, updation, deletion, etc. should all happen via the “Customer” class so that we have proper data integrity maintained.

So when we say load customer from database, all the respective address objects should also get loaded.

So when a group of objects which form one logical unit should have centralized root via which the manipulation of the contained object should happen. This kind of arrangement is terms as “Aggregate Root”.

For Further reading do watch  the below interview preparation videos and step by step video series.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)