title: Fluent Validation on nested class members
body: <p>I have a budgeting app that allows budgets to have N-tier sub budgets. The Class in question is <code>LineItem</code>:</p>
  
  <pre><code>class LineItem
      {
          public string Name { get; set; }
          public Guid Id{ get; set; }
          public ICollection&lt;LineItem&gt; Children = new HashSet&lt;LineItem&gt;();
          public virtual IDictionary&lt;string, double&gt; Budgets {get; set;}          
      }
  </code></pre>
  
  <p>I'm trying to create a Fluent Validator for this class with the following rules in mind:</p>
  
  <ol>
  <li>It is N-Tier... I need to be able to check at every level.</li>
  <li>I need to know at what level (by ID?) the validation failed.</li>
  <li>Validations need to trickle up.</li>
  <li>A null Budget means unlimited... This makes things complicated.</li>
  </ol>
  
  <p>So, for a valid / complex budget example:</p>
  
  <pre><code>validParent (food budget=100)
  ├── child1 (unlimited food budget)
  │   ├── grandchild1 (food budget=15)
  │   ├── grandchild2 (food budget=10)
  └── child2 (food budget=75)
  </code></pre>
  
  <p>and here that same structure that is invalid:</p>
  
  <pre><code>validParent (food budget=100)
  ├── child1 (unlimited food budget)
  │   ├── grandchild1 (food budget=15)
  │   ├── grandchild2 (food budget=70) &lt;- sum of the children on this branch is too much!
  └── child2 (food budget=75) &lt;- not enough left!
  </code></pre>
  
  <p>I have a validator that works at any level with it's child, but only its direct child:</p>
  
  <pre><code>public class BudgetValidator : AbstractValidator&lt;LineItem&gt;
  {
      public BudgetValidator()
      {
          RuleFor(evtNode =&gt; evtNode.Budgets).Custom((budgets, context) =&gt;
          {
              LineItem parent = context.InstanceToValidate as LineItem;
  
              if (parent.Budgets != null) // check if this level is null. if it is, it is valid.
              {
                  IDictionary&lt;string, double&gt; childBudgets = parent.Children.SelectMany(d =&gt; d.Budgets).GroupBy(
                         dict =&gt; dict.Key,
                         dict =&gt;
                         {
                             if (parent.Budgets.ContainsKey(dict.Key) &amp;&amp; parent.Budgets[dict.Key] &lt; dict.Value)
                             {
                                 context.AddFailure($"Invalid child budget ({dict.Key}). Child budget must not exceed that of parent.");
                             }
                             return dict.Value;
                         },
                         (key, g) =&gt; new { Key = key, Value = g.Sum() }
                     ).ToDictionary(e =&gt; e.Key, e =&gt; e.Value);
  
                  foreach (var budget in childBudgets)
                  {
                      if (parent.Budgets.ContainsKey(budget.Key))
                      {
                          if (parent.Budgets[budget.Key] &lt; budget.Value)
                          {
                              context.AddFailure($"Invalid budget. Sum of Budgets ({budget.Key}) must not exceed that of parent.");
                          }
                      }
                  }
              }
          });
  
          RuleForEach(evtNode =&gt; evtNode.Children).SetValidator(this);
      }
  </code></pre>
  
  <p><strong>How can I account for when a level has an "unlimited budget"?</strong> It's children would treat it as "unlimited" but the parent would need to know if the grandchildren exceeded the limit.</p>
  
  <p>Here is a dotnet fiddle with the class
  <a href="https://dotnetfiddle.net/Nkc4ob" rel="nofollow noreferrer">https://dotnetfiddle.net/Nkc4ob</a></p>