简体   繁体   中英

Pass Class Property as Generic Type

I am attempting to implement a base class for FluentValidation that will quickly build a validator for classes. My base class functions attempt to take a class's property as a Generic type argument in order to apply rules. But as you'll see in the code its not quite syntactically (among other things) correct.

It probably much easier to explain in code:

public class BaseValidator<T>  : AbstractValidator<T>
{
    public void ruleForText<U>(string msg)
    {
        RuleFor(obj => obj.U).NotEmpty().WithMessage(msg);
        RuleFor(obj => obj.U).Length(1, 100).WithMessage(msg);
        RuleFor(obj => obj.U).Matches("[A-Z]*").WithMessage(msg);
    }

    public void ruleForEmail<U>(string msg)
    {
        RuleFor(obj => obj.U).NotEmpty().WithMessage(msg);
        RuleFor(obj => obj.U).EmailAddress().WithMessage(msg);
    }
}

public class Member {
    public string Name { get; set; }
    public string Email { get; set; }
}

public class Post{
    public string Title { get; set; }
}

public class MemberValidator :BaseValidator<Member>
{
    public MemberValidator()
    {
        // Not valid syntax to pass name or even Member.Name
        // How can I pass Member.Name as the generic type?
        ruleForText<Name>();
        ruleForEmail<Email>();
    }
}

public class PostValidator :BaseValidator<Post>
{
    public MemberValidator()
    {
        ruleForText<Title>();
    }
}

This might be what you are looking for. You need to pass in an expression with the function parameter being a string.

public class BaseValidator<T> : AbstractValidator<T>
{
    public void RuleForText(Expression<Func<T, string>> expression, string msg)
    {
        RuleFor(expression).NotEmpty().WithMessage(msg);
        RuleFor(expression).Length(1, 100).WithMessage(msg);
        RuleFor(expression).Matches("[A-Z]*").WithMessage(msg);
    }

    public void RuleForEmail(Expression<Func<T, string>> expression, string msg)
    {
        RuleFor(expression).NotEmpty().WithMessage(msg);
        RuleFor(expression).EmailAddress().WithMessage(msg);
    }
}

public class MemberValidator : BaseValidator<Member>
{
    public MemberValidator()
    {
        RuleForText(member => member.Name, "My Message");
        RuleForEmail(member => member.Email, "My Message");
    }
}

public class Member
{
    public string Name { get; set; }
    public string Email { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM