3

I want to loop through my model properties using reflection, and then pass them into a method expecting my property as en expression.

For example, given this model:

public class UserModel
{
    public string Name { get; set; }
}

And this validator class:

public class UserValidator : ValidatorBase<UserModel>
{
    public UserValidator()
    {
        this.RuleFor(m => m.Username);
    }
}

And my ValidatorBase class:

public class ValidatorBase<T>
{
    public ValidatorBase()
    {
        foreach (PropertyInfo property in 
                     this.GetType().BaseType
                         .GetGenericArguments()[0]
                         .GetProperties(BindingFlags.Public | BindingFlags.Insance))
        {
            this.RuleFor(m => property); //This line is incorrect!!
        }
    }

    public void RuleFor<TProperty>(Expression<Func<T, TProperty>> expression)
    {
        //Do some stuff here
    }
}

The issue is with the ValidatorBase() constructor -- given that I have the PropertyInfo for the property I need, what should I pass into as the expression parameter in the RuleFor method, such that it works just like the line in UserValidator() constructor?

Or, should I be using something else besides PropertyInfo to get this to work?

1 Answer 1

6

I suspect you want:

ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
Expression propertyAccess = Expression.Property(parameter, property);
// Make it easier to call RuleFor without knowing TProperty
dynamic lambda = Expression.Lambda(propertyAccess, parameter);
RuleFor(lambda);

Basically it's a matter of building an expression tree for the property... dynamic typing from C# 4 is just used to make it easier to call RuleFor without explicitly doing that via reflection. You could do it, of course - but you'd need to fetch the RuleFor method, then call MethodInfo.MakeGenericMethod with the property type, then invoke the method.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.