Pull to refresh

Comments 14

Извиняюсь, но я правильно понял, что это ваша реализация, доступная через include «Teleavtomatika.Forms», а не фича .NET?
Есть и встроенное решение, интерфейс IDataErrorInfo, который делает тоже самое. На хабре есть несколько статей с примерами его использования в WPF, но можно и для WinForms (ссылка)
Вы забыли про Декларативный стиль. И вот еще, только честно, попробуйте оценить отношение количества кода написанного в декларативном стиле и с использованием IDataErrorInfo.
Я не считаю количество строк, показателем является прозрачность и очевидность кода. Да ваш код выглядит красивым и компактным, но и с имплементацией IDataErrorInfo будет не хуже. Хотите декларированный стиль, можете его обернуть как угодно, c# это позволяет, и получится не хуже, чем .IsValidEMail(false);
По мне — так компактный код в одном месте, который декларирует все предъявляемые условия и не вносит дополнительных зависимостей и есть показатель прозрачности и очевидности.

И еще, с IDataErrorInfo есть проблемы:
1. Нужно определить какой-то тип и реализовать в нем этот интерфейс
2. В этом типе определить метод, который будет фильтровать изменяемые свойства и проверять что там наизменяли
3. Нужно добавить новый контрол (ErrorProvider) на форму и указать ему источник данных (DataSource)
4. Прежде чем это сделать, нужно этот DataSource создать
5. Прежде чем создать DataSource нужно создать какой-то тип для DataSource

т.е. ваш сценарий работает только в связке Данные -> Байндинг на контролы -> Валидация
И еще, с IDataErrorInfo есть проблемы:

Это не проблеммы интерфейса, это его плюсы, потому что не нужно мешать мух и котлеты, а у вас и контролы, и правила, всё вместе. Мне кажется, вы слишком сильно хотите всё декларировать.
Да хватит уже мыслить от контролов…
Код.
С учётом того что вам почти всегда надо INPC property with backing field не выглядят как что-то «сложное».
Конечно, валидацию можно запускать и не на каждый чих — это лишь пример и не более чем…
Ну а в коде формы только биндинг (и тот в дизайнере стряпается на раз-два).
Зачем изобретать FluentValidation? Плюс примешивать UI в валидацию — дурной тон.
Речь идет о валидации форм, а не о валидации данных. FluentValidation это валидация данных в первую очередь. Если речь идет об этом решении fluentvalidation.codeplex.com, мне не очень понятно как из полученных результатов вы сделаете подсветку неправильно заполненных контролов.
Я думаю, что FluentValidation--это валидация с использованием Fluent Interface, и она может быть валидацией чего угодно (данных или форм). У вас в статье, получается, fluent validation форм, следуя вашему разделению.
Ну и лично я (тоже) считаю, что валидация--это всегда валидация данных, и логически принадлежит business logic layer (domain model/services), и должна там находится. UI (View) и/или контроллеры, презентеры, ViewModel должны только вызывать/подключать методы валидации из domain services. Проблема только в том, что эти методы не должны возвращать строки, особенно если строки локализуются.

Совсем идеологически правильный вариант, на мой взгляд, это: 1. Сделать domain validation services (типа CustomerValidationService, OrderValidationService). Методы domain validation services возвращают объект со статусом валидации, кодом ошибки (если надо) и параметрами ошибки (словарь или список) (можно вообще на каждую ошибку сделать свой класс, но это уже оверкилл, по-моему) 2. Если у вас выделены в отдельный подслой presentation services, то пишутся соответствующие presentation validation services, в которые инжектируются domain validation services, и которые собирают коды ошибки во внятные предложения и локализуют, при необходимости. Они возвращают статус и сообщение ошибки, если надо.

При желании можно объединить эти сервисы и сделать так, что методы domain validation services, так и быть, сразу возвращают статус проверки и локализованное сообщение об ошибке.

Ну и дальше можно навешать плюшек: чтоб у каждого сервиса XxxValidationService был метод типа «CombinedValidationStatus DoAllValidations(T item)», выделить базовый класс, который бы имплементил этот метод через рефлексию и атрибуты и все такое. CombinedValidationStatus хранит статус проверки и все сообщения об ошибках, что нашлись. Можно добавить статус проверки типа warning и т.п.

А подключить валидации можно и через FluentInterface, хотя это уже не так важно, по-моему.
Присоединяюсь к тем, кто считает, что валидировать надо данные, а не контролы. Тут лежит старый проект Jeremy Miller (автор StructureMap), который позволяет валидировать данные используя атрибуты и кастомный интерфейс. Как получить из этого помидоры на контролах — другой вопрос, который, впрочем, тоже решается решением, частью которого является эта валидация (тут).
А чому сначала не прибиндили контролы к модельке, а уже потом её валидировать не стали? Или слова MVP, MVVM и MVPVM — ничего не говорящие аббревиатуры?
Sign up to leave a comment.

Articles