Проверка MVC в модели требует хранилища базы данных - PullRequest
3 голосов
/ 30 сентября 2011

Я пишу приложение MVC, используя шаблон репозитория.

Это финансовая система, в которой есть счета.У меня есть проверка в модели счета:

#region IValidatableObject Members

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if ((TotalExcludingTax + (TotalExcludingTax * .15m)) != TotalIncludingTax) {
                yield return new ValidationResult("The total (exc. Tax) + Tax does not equal the total (inc. Tax).");
            }
        }

        #endregion

Проблема в том, что ставка налога .15 является переменной.На данный момент это жестко закодировано здесь, что не очень хорошо.Единственный способ, которым я могу думать об этом:

#region IValidatableObject Members

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var taxRepository = new Repository<tax>();

            if ((TotalExcludingGst + (TotalExcludingGst * taxRepository.GetCurrentTaxRate())) != TotalIncludingGst) {
                yield return new ValidationResult("The total (exc. Gst) + Gst does not equal the total (inc. Gst).");
            }
        }

        #endregion

Используя этот метод, я сейчас создаю экземпляр экземпляра taxRepository в модели счета.

Это плохая практика?

Есть ли лучший способ сделать это?

1 Ответ

3 голосов
/ 30 сентября 2011

Да, ваш текущий подход не велик, и это именно тот сценарий, для которого был создан FluentValidator .

Например, в одном из наших объектов у нас есть некоторая проверка PostCode, которая требует сложных правил, чтобы определить, действителен ли почтовый индекс, поэтому мы делаем что-то вроде этого:

public class AddressValidator : AbstractValidator<Address>
{
    private readonly IPostCodeRepository _postcodeRepo;

    public AddressValidator(IPostCodeRepository postcodeRepo)
    {
        _postcodeRepo = postcodeRepo;

        RuleFor(a => a.Postcode)
                .NotEmpty()
                .WithMessage("Postcode is required")
                .Must(BeValidPostcodeSuburbStateCombo)
                .WithMessage("Postcode is not valid for this state");
    }

    private bool BeValidPostcodeSuburbStateCombo(Address model, string property)
    {
        return _postcodeRepo.ValidatePostcode(model.Postcode, model.Suburb, model.State);
    }
}

Преимущество этого подхода состоит в том, что он сохраняет ваши модели красивыми и чистыми и позволяет проверять сложную логику.

Если переключение на FluentValidator не является для вас вариантом, я бы предложил добавить в вашу модель дополнительное свойство под названием TaxRate и установить его до вызова метода Validate.

Это не идеально, но это означает, что вы не берете зависимость в хранилище в вашей модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...