Проверка должна быть выполнена как можно скорее.
Валидация в любом контексте, модель домена или любой другой способ написания программного обеспечения, должны служить целям того, ЧТО вы хотите проверить и на каком уровне вы находитесь в данный момент.
Исходя из вашего вопроса, я думаю, что ответ будет разделить проверку.
Проверка свойства проверяет, является ли значение этого свойства правильным, например, когда диапазон от 1 до 10 исключен.
Проверка объекта гарантирует, что все свойства объекта действительны в сочетании друг с другом. например, BeginDate до EndDate. Предположим, что вы читаете значение из хранилища данных, и BeginDate и EndDate инициализируются в DateTime.Min по умолчанию. При установке BeginDate нет никаких оснований для применения правила «must be before EndDate», так как это не применяется к YET. Это правило следует проверять ПОСЛЕ того, как были установлены все свойства. Это можно вызвать на уровне совокупного корня
Валидация также должна быть предварительно сформирована для совокупного (или совокупного корневого) объекта. Объект Order может содержать действительные данные, как и его OrderLines. Но затем бизнес-правило гласит, что ни один заказ не может превышать 1000 долларов. Как вы будете применять это правило, в некоторых случаях это разрешено. Вы не можете просто добавить свойство «не проверять сумму», так как это приведет к злоупотреблению (рано или поздно, возможно, даже вы, просто чтобы убрать этот «неприятный запрос»).
Далее идет проверка на уровне представления. Вы действительно собираетесь отправить объект по сети, зная, что он потерпит неудачу? Или вы сэкономите пользователю этот бурдон и сообщите ему, как только он введет недопустимое значение. Например, в большинстве случаев ваша среда разработки будет работать медленнее, чем производство. Хотели бы вы подождать 30 секунд, прежде чем вас проинформируют о том, что «вы забыли это поле СНОВА во время еще ДРУГОГО тестового прогона», особенно когда есть ошибка в работе, которая должна быть исправлена, когда босс дышит вам в шею?
Предполагается, что проверка на уровне постоянства должна быть максимально приближена к проверке значения свойства. Это поможет предотвратить исключения при чтении ошибок «null» или «invalid value» при использовании картографов любого типа или простых старых считывателей данных. Использование хранимых процедур решает эту проблему, но требует написать ту же логику оценки СНОВА и выполнить ее СНОВА. А хранимые процедуры - это область администрирования БД, поэтому не пытайтесь также выполнять ЕГО работу (или, что еще хуже, беспокоите его этой «мелкой добычей, за которую ему не платят»).
так сказать с некоторыми известными словами «это зависит», но по крайней мере теперь вы знаете, ПОЧЕМУ это зависит.
Хотелось бы разместить все это в одном месте, но, к сожалению, этого сделать нельзя. Выполнение этого приведет к зависимости от «объекта Бога», содержащего ВСЕ проверки для ВСЕХ слоев. Вы не хотите идти по этому темному пути.
По этой причине я только выкидываю исключения проверки уровня свойства. На всех других уровнях я использую ValidationResult с методом IsValid, чтобы собрать все «нарушенные правила» и передать их пользователю в одном AggregateException.
При распространении вверх по стеку вызовов я снова собираю их в AggregateExceptions, пока не достигну уровня представления. Сервисный уровень может выдать это исключение прямо клиенту в случае WCF как FaultException.
Это позволяет мне взять исключение и либо разделить его, чтобы показать отдельные ошибки в каждом элементе управления вводом, либо сгладить его и отобразить в одном списке. Выбор за вами.
Вот почему я также упомянул валидацию презентации, чтобы максимально замкнуть их.
Если вам интересно, почему у меня также есть проверка на уровне агрегации (или, если хотите, на уровне обслуживания), это потому, что у меня нет хрустального шара, говорящего мне, кто будет использовать мои услуги в будущем. У вас будет достаточно проблем с поиском собственных ошибок, чтобы другие люди не допускали ошибок ваших, введя неверные данные. Например, вы управляете приложением A, но приложение B передает некоторые данные, используя ваш сервис. Угадай, кого они спрашивают первыми, когда есть ошибка? Администратор приложения B с радостью сообщит пользователю «с моей стороны нет ошибок, я просто передаю данные».