嵌套类成员的流利验证

时间:2018-12-19 15:05:10

标签: c# nested fluentvalidation

我有一个预算应用程序,它允许预算具有N层子预算。有问题的课程是LineItem

class LineItem
    {
        public string Name { get; set; }
        public Guid Id{ get; set; }
        public ICollection<LineItem> Children = new HashSet<LineItem>();
        public virtual IDictionary<string, double> Budgets {get; set;}          
    }

我正在尝试使用以下规则为此类创建Fluent验证程序:

  1. 这是N层……我需要能够在每个级别进行检查。
  2. 我需要知道在什么级别(通过ID?)验证失败。
  3. 验证需要进行滴灌。
  4. 空预算意味着无限...这使事情变得复杂。

因此,对于有效/复杂的预算示例:

validParent (food budget=100)
├── child1 (unlimited food budget)
│   ├── grandchild1 (food budget=15)
│   ├── grandchild2 (food budget=10)
└── child2 (food budget=75)

这里是无效的相同结构:

validParent (food budget=100)
├── child1 (unlimited food budget)
│   ├── grandchild1 (food budget=15)
│   ├── grandchild2 (food budget=70) <- sum of the children on this branch is too much!
└── child2 (food budget=75) <- not enough left!

我有一个验证器,可以在任何级别上与它的孩子一起工作,但只能是其直接孩子:

public class BudgetValidator : AbstractValidator<LineItem>
{
    public BudgetValidator()
    {
        RuleFor(evtNode => evtNode.Budgets).Custom((budgets, context) =>
        {
            LineItem parent = context.InstanceToValidate as LineItem;

            if (parent.Budgets != null) // check if this level is null. if it is, it is valid.
            {
                IDictionary<string, double> childBudgets = parent.Children.SelectMany(d => d.Budgets).GroupBy(
                       dict => dict.Key,
                       dict =>
                       {
                           if (parent.Budgets.ContainsKey(dict.Key) && parent.Budgets[dict.Key] < dict.Value)
                           {
                               context.AddFailure($"Invalid child budget ({dict.Key}). Child budget must not exceed that of parent.");
                           }
                           return dict.Value;
                       },
                       (key, g) => new { Key = key, Value = g.Sum() }
                   ).ToDictionary(e => e.Key, e => e.Value);

                foreach (var budget in childBudgets)
                {
                    if (parent.Budgets.ContainsKey(budget.Key))
                    {
                        if (parent.Budgets[budget.Key] < budget.Value)
                        {
                            context.AddFailure($"Invalid budget. Sum of Budgets ({budget.Key}) must not exceed that of parent.");
                        }
                    }
                }
            }
        });

        RuleForEach(evtNode => evtNode.Children).SetValidator(this);
    }

当一个级别具有“无限预算”时,我该怎么解释?孩子将其视为“无限预算”,但是父母需要知道孙子是否超出了限制。 >

这是一个与班级有关的dotnet小提琴 https://dotnetfiddle.net/Nkc4ob

0 个答案:

没有答案