Должен ли я помещать логику проверки в POCO?
Скажем, у меня есть POCO, например:
public class Name
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Имя FirstName и LastName не может быть нулевым. Должен ли я добавить такой метод:
public List<Error> Validate()
{
var errors = new List<Error>();
if (String.IsNullOrEmpty(FirstName))
errors.Add(new Error("FirstName", "You must fill out first name."));
if (String.IsNullOrEmpty(LastName))
errors.Add(new Error("LastName", "You must fill out last name."));
}
где Error
- это структура, содержащая a NameValueDictionary
. Это хороший способ сделать что-то? Я могу потенциально увидеть проблему с репозиторием, где кто-то пытается сохранить этот POCO, прежде чем запускать его через Validate()
.
Ответы
Ответ 1
Рассмотрим использование аспектно-ориентированной структуры проверки, например xVal.
Вместо того, чтобы включать ваши правила проверки непосредственно в код, вы можете добавить их как атрибуты своих свойств и разгрузить зависимость. Ваш класс будет выглядеть следующим образом:
public class Name
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
Чтобы более точно ответить на ваш вопрос, добавление правил проверки в ваш POCO - это простой способ делать то, что будет работать, но оно может стать тяжелым для поддержания, и вам нужно будет обеспечить интерфейс Validate для всех ваших объектов, которая является собственной головной болью. Аспектно-ориентированное решение довольно элегантное, которое решает эти проблемы и многие другие.
Ответ 2
Я бы не стал. Мой POCO имеет тенденцию иметь другую валидацию, основанную на их контексте. "Объекты My Person должны иметь адрес в этом приложении, но они должны иметь только номер телефона в этом другом приложении"... это то, о чем вы хотите следить и быть гибким.
Я сторонник модели анемичного домена, поскольку я обычно повторно использую один и тот же домен, но назначаю другое поведение и проверку на основе контекста (которые могут быть даже разными областями одного и того же приложения).
При внедрении новых функций я обычно смотрю на свой класс и задаю себе этот вопрос: похоже ли это, как ответственность этого класса, или он будет более подходящим для класса с другим набором обязанностей? Мы называем эту проверку "Feature Envy", и она эффективно помогает отделить класс и не беспокоится о нем.
Ответ 3
Я не нахожу ничего неправильного в проверке в модели. Он хорошо работает со всеми технологиями Microsoft UI, которые ожидают, что модель может быть задана, если она действительна или нет, и вы не сохраняете отображение одного DTO другому, только чтобы завершить повторение вашей проверки в модели просмотра или редактирования (или хуже, ТОЛЬКО ставить его там).
Правила в вашем примере просты, но вам часто приходится писать более сложные правила. Вероятно, вы должны проверить структуру Csla.Net.