2

I have a class and my validation looks like this:

    public ValidationResult Validate(CustomerType customerType)
    {
        CustomerType Validator validator = new CustomerTypeValidator();
        validator.RuleFor(x => x.Number).Must(BeUniqueNumber);

        return validator.Validate(customerType);
    }

    public bool BeUniqueNumber(int number)
    {
        //var result = repository.Get(x => x.Number == customerType.Number)
        //                       .Where(x => x.Id != customerType.Id)
        //                       .FirstOrDefault();

        //return result == null;
        return true;
    }

The CustomerTypeValidator is a basic validator class that validates string properties.

I also add a new rule to check if the number is unique in the db. I do it in this class because there's a reference to the repository. The validator class has no such reference.

The problem here is that the BeUniqueNumber method should have a CustomerType parameter. However when I do this, I get an error on the RuleFor line above because 'Must' needs an int as a parameter.

Is there a way around this?

1 Answer 1

3

Can you try this?

public ValidationResult Validate(CustomerType customerType)
{
    CustomerTypeValidator validator = new CustomerTypeValidator();
    validator.RuleFor(x => x).Must(HaveUniqueNumber);

    return validator.Validate(customerType);
}

public bool HaveUniqueNumber(CustomerType customerType)
{
    var result = repository.Get(x => x.Number == customerType.Number)
        .Where(x => x.Id != customerType.Id)
        .FirstOrDefault();

    return result == null;
    //return true;
}

You should also be able to do this:

public ValidationResult Validate(CustomerType customerType)
{
    CustomerTypeValidator validator = new CustomerTypeValidator();
    validator.RuleFor(x => x.Number).Must(BeUniqueNumber);

    return validator.Validate(customerType);
}

public bool BeUniqueNumber(CustomerType customerType, int number)
{
    var result = repository.Get(x => x.Number == number)
        .Where(x => x.Id != customerType.Id)
        .FirstOrDefault();

    return result == null;
    //return true;
}

"I also add a new rule to check if the number is unique in the db. I do it in this class because there's a reference to the repository."

Well, why can't you give your validator a reference to the repository too?

CustomerTypeValidator validator = new CustomerTypeValidator(repository);
Sign up to request clarification or add additional context in comments.

6 Comments

I tried that too. It doesn't work because 'Must' needs <T, TProperty>
@Ivan-MarkDebono that's odd, are you sure? I just tried something very similar, and the Predicate method only needs a T, not a TProperty. Are you sure you are doing x => x, and not x => x.Number? I have also updated my answer with another alternative.
I've already tried both ways and they won't work. I'd rather not pass the repository around if there's a solution without doing so.
@Ivan-MarkDebono what version of fluent validation are you using? Are you getting a compiler / build error? If so, what is the exact error? Like I said, the above code works when I build it (against FluentValidation 5.0.0.1). Could you provide the source for your CustomerType and CustomerTypeValidator in the OP?
My bad. Your answer with the first example works fine. I had BeUniqueNumber() when I re-edited the code.
|

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.