Свободная проверка на вложенных классах - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть приложение для составления бюджета, которое позволяет бюджетам иметь суб-бюджеты 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;}          
    }

Я пытаюсь создать Fluid Validator для этого класса с учетом следующих правил:

  1. Это N-Уровень ... Мне нужно иметь возможность проверять на каждом уровне.
  2. Мне нужно знать, на каком уровне (по идентификатору?) Проверка не удалась.
  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);
    }

Как я могу объяснитькогда уровень имеет «неограниченный бюджет»? Это дети будут рассматривать его как «неограниченный», но родитель должен знать, если внуки превысили лимит.

Вот скрипка дотнет с классомhttps://dotnetfiddle.net/Nkc4ob

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...