mardi 8 mars 2016

How to use Reflection in FluentValidation?

I have a scneario in which I want to use reflection to do validation using FluentValidation. Someting like this:

public class FooValidator : AbstractValidator<Foo>
{
    public FooValidator(Foo obj)
    {
        // Iterate properties using reflection
        var properties = ReflectionHelper.GetShallowPropertiesInfo(obj);
        foreach (var prop in properties)
        {
            // Create rule for each property, based on some data coming from other service...
            //RuleFor(o => o.Description).NotEmpty().When(o => // this works fine when foo.Description is null
            RuleFor(o => o.GetType().GetProperty(prop.Name)).NotEmpty().When(o =>
            {
                return true; // do other stuff...
            });
        }
    }
}

The call to ReflectionHelper.GetShallowPropertiesInfo(obj) returns "shallow" properties of object. Then, for each property I create a rule. This is my code for get properties of object:

public static class ReflectionHelper
{
    public static IEnumerable<PropertyInfo> GetShallowPropertiesInfo<T>(T o) where T : class
    {

        var type = typeof(T);
        var properties =
            from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            where pi.PropertyType.Module.ScopeName == "CommonLanguageRuntimeLibrary"
                && !(pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>))
            select pi;

        return properties;
    }
}

This code compile and can be executed

IValidator<Foo> validator = new FooValidator(foo);
var results = validator.Validate(foo);

But it doesn't work properly (validation never fails). Is there any way to achieve this?

Note: Demo code can be found int Github at FluentValidationReflection





Aucun commentaire:

Enregistrer un commentaire