2

I have a graph of objects more than two levels deep. It represents an entity with children and grandchildren (an aggregate):

A → B → C

I want to validate at all levels of the graph. I know I can access A when validating B using an overload of Must() or using a Custom() rule. I haven't figured out how to use these two techniques for accessing A from C's validator because there appears to be no context for that.

The only way I was able to do what I wanted was to create a new object that is a flattened representation. In other words create a wrapper that places A and C on the same level, which allows me to use the Must() overload on C to get to A on the pseudo-parent Wrapper.

Wrapper → A → B → C
        → C

The problem is that I have to create yet another validator (for Wrapper in this case). I'd prefer to keep all my validation logic for a particular thing together.

Is there another way?

Community
  • 1
  • 1
Kit
  • 20,354
  • 4
  • 60
  • 103

1 Answers1

0

I tried to put together your case in code, so we could work on it and find a solution.

using FluentValidation;
namespace FluentDemo
{
    class Program
    {
        static void Main(string[] args) 
        {
            // TODO
        }
    }
    class A
    {
        public string MyProperty { get; set; }
    }
    class B
    {
        public string OtherProperty { get; set; }
        public A A { get; set; }
    }
    class C
    {
        public string DifferentProperty { get; set; }
        public B B { get; set; }
    }
    class AValidator : AbstractValidator<A>
    {
        public AValidator()
        {
            RuleFor(a => a.MyProperty)
                .NotNull(); 
        }
    }
    class BValidator : AbstractValidator<B>
    {
        public BValidator(IValidator<A> aValidator)
        {
            RuleFor(b => b.OtherProperty)
                .NotNull();

            RuleFor(b => b.A)
                .SetValidator(aValidator);
        }
    }
    class CValidator : AbstractValidator<C>
    {
        public CValidator(IValidator<B> bValidator)
        {
            RuleFor(c => c.DifferentProperty)
                .NotNull();

            RuleFor(c => c.B)
                .SetValidator(bValidator);
        }
    }
}
Edgars Pivovarenoks
  • 1,526
  • 1
  • 17
  • 31