Комментарии 14
Извиняюсь, но я правильно понял, что это ваша реализация, доступная через include «Teleavtomatika.Forms», а не фича .NET?
Да, вы поняли правильно.
Есть и встроенное решение, интерфейс
IDataErrorInfo
, который делает тоже самое. На хабре есть несколько статей с примерами его использования в WPF, но можно и для WinForms (ссылка)Вы забыли про Декларативный стиль. И вот еще, только честно, попробуйте оценить отношение количества кода написанного в декларативном стиле и с использованием
IDataErrorInfo
.Я не считаю количество строк, показателем является прозрачность и очевидность кода. Да ваш код выглядит красивым и компактным, но и с имплементацией
IDataErrorInfo
будет не хуже. Хотите декларированный стиль, можете его обернуть как угодно, c# это позволяет, и получится не хуже, чем .IsValidEMail(false);
По мне — так компактный код в одном месте, который декларирует все предъявляемые условия и не вносит дополнительных зависимостей и есть показатель прозрачности и очевидности.
И еще, с
1. Нужно определить какой-то тип и реализовать в нем этот интерфейс
2. В этом типе определить метод, который будет фильтровать изменяемые свойства и проверять что там наизменяли
3. Нужно добавить новый контрол (
4. Прежде чем это сделать, нужно этот
5. Прежде чем создать
т.е. ваш сценарий работает только в связке Данные -> Байндинг на контролы -> Валидация
И еще, с
IDataErrorInfo
есть проблемы: 1. Нужно определить какой-то тип и реализовать в нем этот интерфейс
2. В этом типе определить метод, который будет фильтровать изменяемые свойства и проверять что там наизменяли
3. Нужно добавить новый контрол (
ErrorProvider
) на форму и указать ему источник данных (DataSource
)4. Прежде чем это сделать, нужно этот
DataSource
создать5. Прежде чем создать
DataSource
нужно создать какой-то тип для DataSource
т.е. ваш сценарий работает только в связке Данные -> Байндинг на контролы -> Валидация
И еще, с IDataErrorInfo есть проблемы:
Это не проблеммы интерфейса, это его плюсы, потому что не нужно мешать мух и котлеты, а у вас и контролы, и правила, всё вместе. Мне кажется, вы слишком сильно хотите всё декларировать.
Да хватит уже мыслить от контролов…
Код.
С учётом того что вам почти всегда надо INPC property with backing field не выглядят как что-то «сложное».
Конечно, валидацию можно запускать и не на каждый чих — это лишь пример и не более чем…
Ну а в коде формы только биндинг (и тот в дизайнере стряпается на раз-два).
Код.
С учётом того что вам почти всегда надо INPC property with backing field не выглядят как что-то «сложное».
Конечно, валидацию можно запускать и не на каждый чих — это лишь пример и не более чем…
Ну а в коде формы только биндинг (и тот в дизайнере стряпается на раз-два).
Зачем изобретать FluentValidation? Плюс примешивать UI в валидацию — дурной тон.
Речь идет о валидации форм, а не о валидации данных. FluentValidation это валидация данных в первую очередь. Если речь идет об этом решении fluentvalidation.codeplex.com, мне не очень понятно как из полученных результатов вы сделаете подсветку неправильно заполненных контролов.
Ну и лично я (тоже) считаю, что валидация--это всегда валидация данных, и логически принадлежит 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, хотя это уже не так важно, по-моему.
Совсем идеологически правильный вариант, на мой взгляд, это: 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 — ничего не говорящие аббревиатуры?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Валидация форм в декларативном стиле (C#)