I have a Tree.
class TreeNode { public TreeNode(string name, string description) { Name = name; Description = description; } string Name { get; set; } string Description { get; set; } public List<TreeNode> Children = new List<TreeNode>(); }
I would like to populate a large one for unit testing purposes. I would really like to keep stuff DRY.
Say for illustration purposes my tree has the following structure
Parent,desc Child 1, desc1 Grandchild 1, desc1 Child 2, desc2
How would you go about populating the tree in an elegant an maintainable way?
I find this code quite repetitious and error prone:
var parent = new TreeNode('Parent', 'desc'); var child1 = new TreeNode('Child 1', 'desc1'); var child2 = new TreeNode('Child 2', 'desc2'); var grandchild1 = new TreeNode('Grandchild 1', 'desc1'); parent.Children.Add(child1); parent.Children.Add(child2); child1.Children.Add(grandchild1);
EDIT
I ended up doing the DSL approach:
A demo test lives here.
It uses a builder and a simple DSL.
Ideally you want a way to extend the language to literals of custom types. C# doesn’t have this, so you have to find another approach.
You can fabricate an internal DSL, typically with a fluent interface.
Follow the
XElementexample of functional construction.Create an external DSL with a custom parser. If you design the language carefully, the parser can be easy.
Use XML. Basically this is a way to create an external DSL and get the parser for free.
The external DSL options are nice because when you read them, you know there’s only data, and don’t have to worry about making sense of code constructs. Also, the data is the file, and the file is the data. That makes it easy to swap data around by changing files, and easier to ready file change histories. Finally, and external DSL is good when a non-programmer will be supplying the data.
The tradeoff here is time vs. value. How much data you will have / how often it will change / who will change it are the questions you have to answer.