IValidatableObject vs Single Responsibility


12

Мені подобається точка екстенсивності MVC, що дозволяє переглядати моделі для реалізації IValidatableObject і додавати спеціальну перевірку.

Я намагаюся тримати мої контролери слабкими, оскільки цей код є єдиною логікою перевірки:

if (!ModelState.IsValid)
    return View(loginViewModel);

Наприклад, модель перегляду входу реалізує IValidatableObject, отримує об'єкт ILoginValidator за допомогою конструкторської інжекції:

public interface ILoginValidator
{
    bool UserExists(string email);
    bool IsLoginValid(string userName, string password);
}

Здається, що Ninject, введення інстанцій у переглянуті моделі насправді не є звичайною практикою, може бути навіть анти-закономірністю?

Це хороший підхід? Чи є кращий?


Якщо ви хочете перевірити в окремому об'єкті, спробуйте FluentValidation. Дивіться сторінку fluentvalidation.codeplex.com/wikipage?title=mvc .
rmac

+1 Відмінна ідея ввести окремий клас Validator, який вирішує мою проблему, де я маю доступ до інформації бази даних для перевірки!
магнатський

Відповіді:


7

Особисто мені дизайн здається чистим.

IValidatableObject означає, що модель перегляду надасть певну валідацію, яку не можна забезпечити простими атрибутами - введення справжнього валідатора, який викликає послуги / бази даних / все, що забезпечує ваш дизайн чистим і гарантує, що ви не порушите принцип єдиної відповідальності - Моделі перегляду відповідальний, по суті, за передачу даних і перевірку даних, що передаються (будь то через атрибути або IValidatableObject або те й інше).


4

Наявність виділеного об'єкта для валідації гарантує, що ви дійсно поважаєте SRP - що вже було так, оскільки типовою відповідальністю моделі перегляду є перевірка його даних.

Що стосується введення екземплярів у моделі перегляду, я не можу бачити нічого поганого в цьому. Практично немає меж того, що можна вводити в що.


3

Замість того, щоб вводити ILoginValidator у свій конструктор VM, ви можете використовувати ValidationContext (що є аргументом IValidatableObject.Validate ()), щоб отримати валідатор.

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

var loginValidator = (ILoginValidator)vc.GetService(typeof(ILoginValidator));
return loginValidator.Validate();

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.