Builder Template with Nested Objects

Hi, I have a problem.

I want to implement a builder pattern to make it easier to create my objects. The problem I am facing is with a nested object. The object that I would like to create has a list of other objects in it, and I really don't know how to solve it.

I want to be able to do the following (e.g. simple objects):

Receipt RestaurantReceipt = new ReceiptBuilder() .withDate("value") .withName("value") .AddItem("value") .WithIngredients("value") .WithType("value") .AddItem("value") .WithIngredients("value") .WithType("value") .build(); 

Or something like:

 Receipt RestaurantReceipt = new ReceiptBuilder() .withDate("value") .withName("value") .AddItem("value", item => { .WithIngredients("value") .WithType("value") }) .AddItem("value", item => { .WithIngredients("value") .WithType("value") }) .build(); 

The example should be representative for my situation, although if more than one type of nested object is received.

+6
source share
1 answer

Given code like this

 var rb = new ReceiptBuilder(); var receipt = rb.WithName("Name") .WithDate(DateTime.Now) .WithItem("Item1", i => i.WithIngredients("Ingredients1")) .WithItem("Item2", i => i.WithIngredients("Ingredients1")) .Build(); Console.WriteLine(receipt); 

Your builder is fairly simple, using some simple predicates inside the AddItem builder method to allow the user to configure each item in a similar builder pattern to the top level of ReceiptBuilder :

 public class ReceiptBuilder { private Receipt r; public ReceiptBuilder() { r = new Receipt(); } public ReceiptBuilder WithName(string name) { r.Name = name; return this; } public ReceiptBuilder WithDate(DateTime dt) { r.Date = dt; return this; } public ReceiptBuilder WithItem(string text, Action<ReceiptItemBuilder> itemBuilder) { var rib = new ReceiptItemBuilder(text); itemBuilder(rib); r.AddItem(rib.Build()); return this; } public Receipt Build() { return r; } } public class ReceiptItemBuilder { private ReceiptItem ri; public ReceiptItemBuilder(string text) { ri = new ReceiptItem(text); } public ReceiptItemBuilder WithIngredients(string ings) { ri.Ingredients = ings; return this; } // WithType omitted for brevity. internal ReceiptItem Build() { return ri; } } 

Working example: http://rextester.com/IRR50897

+6
source

All Articles