Вот сценарий:Рекомендации по POCO Validation с ASP.NET MVC/Entity Framework
- ASP.NET Web Application MVC2
- Entity Framework 4 (Pure, контекст пользовательских данных Poco в)
- Repository Pattern
- Единица работы шаблон
- Dependency Injection
- Service Layer посредническую Controller -> Repository
Итак, в основном, все классные вещи. :)
Поток событий для основной работы пользовательского интерфейса ("Добавление Post"):
- контроллер вызывает Add (Post) метод на уровне услуг
- Service слой вызывает Add (T) на хранилище
- Repository вызовы AddObject (T) на пользовательском контексте данных
- контроллер вызывает Comm it() на единице работы
Теперь, я пытаюсь выяснить, где я могу проверить.
На данном этапе, мне нужно два типа проверки:
- Простые, независимо ПОКА проверка, такие как «пост должен иметь название». Это кажется естественным для Data Annotations на POCO.
- Сложная проверка бизнеса, такая как «невозможно добавить комментарий к заблокированному сообщению». Это невозможно сделать с помощью аннотаций данных.
Теперь, я читал «Программирование Entity Framework, Second Edition» Джули Лерман (которое отлично BTW), и искали в закреплять в SavingChanges случае для того, чтобы выполнить «в последнюю минуту» валидация , Это было бы хорошим способом убедиться, что валидация всегда происходит всякий раз, когда я делаю «что-то» (добавление, изменение, удаление), но это также немного поздняя IMO (поскольку элементы уже находятся в диспетчере состояний) - так что я могу делать, если проверка не удалась, удалить их?
Я мог бы, конечно, реализовать свой интерфейс POCO (скажем, «IValidatable») и вызвать метод на этом интерфейсе во время этого события.
Но это кажется «слишком поздно» для подтверждения бизнеса - это консенсус?
Я в основном ищу руководство здесь, я пытаюсь разработать повторно используемую интеллектуальную схему проверки сложной бизнес-логики, учитывая мою вышерасположенную архитектуру.
Другой кривой мяч для вас - как вы знаете, ПОКО с EF означает ПОКО имеют все свойства на БД - так что я мог бы иметь свойство «сообщения дан», с Get/Set аксессорах (как потребности EF чтобы получить/установить эти свойства).
Но проблема в том, что «Почтовый идентификатор» - это идентификатор , так как я могу защитить поле от того, чтобы быть установленным? Например, если я (по некоторым причинам) сделайте следующее:
var post = service.FindSingle(10);
post.PostId = 10;
unitOfWork.Commit();
Это будет бросать SqlException. Как я могу предотвратить это? Я не могу «спрятать» свойство (сделать его приватным или даже внутренним), поскольку POCO находятся в отдельной сборке в репозитории.
Примечание по проверке - я планирую создавать пользовательские исключения (исходя из Исключения). Поэтому, когда проверка не выполняется, мне нужно бросить эти исключения.
Таким образом, я могу закодировать что-то вроде этого на мой контроллер:
[HttpPost]
public ActionResult AddPost(Post post)
{
try
{
IUnitOfWork uow = new UnitOfWork();
postService.Add(post);
uow.Commit();
}
catch(InvalidPostOperation ipo)
{
// add error to viewmodel
}
}
мне придется вручную делать проверку на обслуживание слоя каждый раз я сделать надстройку? Тогда как я могу справиться с сохранением? (так как это находится на Единице работы, а не на уровне обслуживания).
Таким образом, чтобы предотвратить это, чтобы быть «повсюду» вопрос, вот мои вопросы:
- Простая проверка ПОКО - это должно быть сделано с аннотациями данных? Плюсы/минусы/подводные камни?
- При каких обстоятельствах (если таковые имеются) мы должны подключаться к событию EF Data Context для подтверждения, чтобы связать его с SavingChanges?
- Где я должен выполнять комплексную проверку бизнеса? В службе explicity или метод на POCO (который я могу позвонить из службы). Как создать интеллектуальную/многоразовую схему?
- Как мы можем «спрятать» автогенерируемые свойства POCO от подделки?
Любые мысли были бы наиболее ценными.
Извините, если этот пост «слишком длинный», но это важная проблема, и это решение может быть решено многими способами, поэтому я хотел предоставить всю информацию для наилучшего возможного ответа.
Спасибо.
EDIT
Ниже ответ полезно, но я до сих пор (в идеале) ищет больше мыслей. Кто-нибудь еще?
Слишком много вопросов в одном, но относительно № 3, имейте в виду, что проверка чувствительна к контексту (или основана на задачах). Заманчиво создать свойство 'IsValid' на вашем' Post', но где-то вдоль строки вам понадобится 'IsValidForDraft', который используется для сохранения черновиков, которым не хватает определенной информации. И, конечно же, POCO не должен знать концепцию «проекта публикации». :) – bzlm
Да ладно, почему голосование закрывается? Я понимаю его «длинный» вопрос. Но вот почему у меня есть 4 вопроса в конце. Просто потому, что я спрашиваю 4 вещи, не означает, что это Q заслуживает голосования, чтобы закрыться за то, что он «слишком расплывчатый». Все 4 q относятся к одной теме. – RPM1984
@bzlm - да, ваша точка зрения. :) – RPM1984