-
Notifications
You must be signed in to change notification settings - Fork 25
Entity Tree Overview
The rest of the TreeCollections library focuses on the EntityTreeNode generic class, specifically its two variations: MutableEntityTreeNode and ReadOnlyEntityTreeNode. Before diving into examples, let's look at some of the goals and reasoning behind these classes.
The ability to distinguish between read-only trees and those that can be modified was a fundamental design decision. When building applications, it is often desirable to expose information through a query-able structure which does not allow changes. The ReadOnlyEntityTreeNode class allows for this immutability.
An EntityTreeNode contains an inner entity object which is exposed through the Item property. This allows the core entity class to be designed independently of the container node class (and thus independent of the TreeCollections library); no inheritance is required. This promotes a clean separation of concerns between an entity's core properties/behaviors and its hierarchical aspects.
It is possible - and highly encouraged - to create your own custom EntityTreeNode class derivations, if for no other reason than to avoid passing around objects with multiple type parameters. Beyond this, there are a handful of protected virtual methods that can be overridden to modify behavior and enforce business constraints.
Given a type TNode where TNode inherits from EntityTreeNode, note this fundamental relationship:
TNode : IEnumerable<TNode>
That is, a single TNode object exposes an enumerator (of TNode) and thus is fully LINQ compatible.
The default enumerator is a pre-order (depth-first) iterator, but more advanced capabilities are possible.
Given a variable root of typeTNode, consider the following:
IEnumerable<TNode> all = root.Select(n => n);
Here, we create a sequence that contains the root itself and all its descendants in depth-first order.
Another example:
IEnumerable<TNode> sNodes = root.Where(n => n.Item.Name.StartsWith("S"));
Here, we create a sequence of all nodes from the root whose core entity name starts with "S".
It is often important that we can ensure uniqueness of nodes in a tree and particularly that no cycles exist. Also, it is a common requirement that no 2 siblings in a hierarchy have the same name. Enforcement of these rules are configurable in all EntityTreeNode classes.