Если DTO и Entity имеют входные проверки

У меня есть WCF-слой, и моя модель домена находится за этим слоем WCF. Я использую Nhibernate как инструмент ORM, и вся моя бизнес-логика/Data Access и т.д. Будут за этим слоем WCF.

Я подвергаю DTO своим клиентам. У меня есть вопросы

1) Должен ли я создавать DTO? есть ли какой-либо вред в экспонировании объектов непосредственно клиенту wcf, поскольку мои сущности также будут иметь методы бизнес-логики, поэтому я должен был бы повредить свой объект entitiy с атрибутами WCF, которые, я думаю, не хороши?

2) Если я выставить DTO, я должен проверять DTO, а также Entity. Если я проверяю только DTO, то я не предоставляю никаких входных проверок для моего объекта Enitity. это нормально?

3) Должен ли я рассмотреть возможность проверки DTO на уровне Application Service (уровень WCF) с помощью проверки схемы? или Я должен использовать подход IValidator, приведенный в статье [blog]: http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/, как показано Джимми Богардом

Наличие DTO порой кажется излишним для меня, но я могу использовать его в деталях клуба из одного или нескольких объектов.

Я бы разоблачил эту услугу для разных клиентов, и, таким образом, мой DTO будет извлекаться из некоторого базового dto с данными учетных данных, которые я бы проверял для каждого входящего запроса до моего фактического вызова метода wcf (возможно, используя IEndpointBehaviour и IParamInspector)


Изменить

Основываясь на ответе, я сейчас соглашусь сохранить слой DTO. Вот пример, чтобы сценарий стал более явным.

Скажем, у меня есть метод CreateCustomer, который принимает CustomerDetailsDTO на моем уровне службы приложений WCF, который может быть вызван приложением MVC. Существуют некоторые входные проверки, такие как

Входные проверки:

i)Name length should be greater than 2 but less than 50
ii) Age is mandatory and cann not be less than 18
(Different other field validations)etc 

Бизнес-проверки:

There could then be some business rules to check for dupliate customer 
based on say email or some other factor whcih i think should be part of
my Domain business logic and should reside in CustomerEntity class.

Если входная проверка применяется только на уровне интерфейса службы, поскольку мы получаем DTO от клиента или он также должен применяться к CustomerEntity

Ответ 1

1) Должен ли я создавать DTO? есть ли какой-либо вред в экспонировании объектов непосредственно клиенту wcf, поскольку мои сущности также будут иметь методы бизнес-логики, поэтому я должен был бы повредить свой объект entitiy с атрибутами WCF, которые, я думаю, не хороши?

Да, для SOA требуются контракты данных.

Они могут быть более или менее формализованы (CSV, JSON, XSD, WSDL, WADL, даже HTML или txt файл), но если вы не можете найти соглашение по таким контрактам, вы не должны использовать какую-либо "сервисную" технологию или техникой (или любым другим IPC, для чего это важно).

Remoting была единственной технологией, которая пыталась избежать такого требования. Это была удивительная идея, абстрактно, но конкретно это не сработало.

2) Если я выставить DTO, я должен проверять DTO, а также Entity. Если я проверяю только DTO, то я не предоставляю никаких входных проверок для моего объекта Enitity. это нормально?

Вы должны подтвердить "контракт", а не бизнес-правила.

Например, WCF DTO может потребовать заполнения некоторых полей, и я использовал бы ArgumentNullException в конструкторах.

Но вы должны помнить, что DTO служат для передачи данных. Если у вас есть числовое поле, которое по какой-то странной причине должно быть передано в виде строки, вы можете проверить его, например, предотвратить инициализацию DTO.

3) Должен ли я рассмотреть возможность проверки DTO на уровне Application Service (уровень WCF) с помощью проверки схемы? или Если я использую подход IValidator, приведенный в статье [blog]: http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/, как показано Джимми Богардом

Если вам нужна модель домена (это означает, что вам нужно нанять эксперта, чтобы понять цель приложения), он должен быть единственным ответственным за бизнес-правила, Таким образом, для простых проверок вам не нужна никакая система проверки.

Вам нужны экспрессивные исключения, которые могут быть легко сопоставлены с правильно определенными ошибками.

изменить ответ на новые вопросы

В WCF я часто использую проверку ввода в конструкторах DTO, так что клиент не может отправлять "недопустимые запросы". Это имеет много преимуществ, например, клиент не может использовать недопустимый ввод для настройки атаки DOS, например. Более того, если у вас большое количество клиентов, это может снизить нагрузку на сеть и сделать работу пользователя немного лучше, так как ему не нужно ждать ответа сервера, чтобы знать, что он забыл @в поле электронной почты.

Но на самом деле быть старше 18 - это бизнес-правило, а не правило ввода.

Правило ввода может быть: "Поле возраста должно быть больше нуля", потому что отрицательный возраст невозможен, а нулевой возраст слишком сильно напоминает ошибку пользователя (и это значение по умолчанию для int32).

Однако проверка контракта не достаточно .

Если возраст имеет значение в вашем домене, у вас будет структура Age, обертывающая UInt32 (таким образом, правило input). Зачем завершать UInt32? Например, поскольку в вашей модели домена вы знаете, что сумма возраста двух пользователей не имеет значения.

Да, вы проверяете это число не более 3 раз (одно на клиенте и два на сервере), но это правильно, вот здесь. DTO могут развиваться независимо от модели домена, и модель домена не может рисковать неожиданным (или вообще не нужна модель домена).

Чтобы получить представление о бизнес-правиле, подумайте о приложении медицинской записи, которое отслеживает какой-то специализированный вид терапии: command void Prescribe(Age patientAge, AntibioticPrescription prescription) может проверить, что оба аргумента patientAge больше, чем предыдущий возраст рецепта. Это правило бизнес. Другое деловое правило должно проверять наличие опасных взаимодействий между текущим рецептом и предыдущим.

Если это так, эта команда должна документировать и бросать 3 исключения:

  • ArgumentNullException, когда рецепт равен null (если он является ссылочным типом)
  • InconsistentAge, когда предоставленный пациент ниже, чем последний,
  • MortalPrescription, когда такой рецепт может убить пациента.

Такие исключения выражают предварительные условия, которые являются бизнес правилами (за исключением аргумента null, который должен терпеть неудачу так быстро насколько это возможно, когда программисты вводят какие-то ошибки).

Ответ 2

наличие DTO всегда полезно скрыть наши объекты домена от любого пользовательского интерфейса или внешней обработки. Это также позволяет создавать немного другую структуру объектов, потому что ваша модель домена может быть довольно плотной для вашей диаграммы базы данных и не всегда должна отражать логический смысл объектов.

Значение, нет, вы не должны подвергать объекты напрямую через службы.

Чтобы преобразовать объекты в DTO, я использую Automapper в большинстве сценариев, что довольно удобно.

Что касается проверки, вы можете использовать аннотации данных для своих объектов для проверки их, например.

Но если ваши DTO отражают различную или более сложную бизнес-логику, которую невозможно проверить только с помощью аннотаций, вы можете использовать что-то вроде плавная проверка, который очень гибкий и простой в настройке.

В настоящее время я использую их в одном проекте. Например, для стандартных проверок, таких как обязательные поля, длина поля или даже проверка по электронной почте или номеру телефона, вы можете использовать простые аннотации данных с регулярными выражениями и т.д.

Для сложных вещей, например, если поле A пустое поле B не должно быть пустым и т.д., вы можете свободно использовать проверку... И это действительно зависит, если вы делаете это на уровне сущности или DTO. Если у вас нет какой-либо пользовательской логики, отраженной только DTO, которая может быть View Model (с точки зрения MVC), вы можете сделать все это на уровне сущности.

Это также зависит от того, является ли ваше приложение единственным приложением, использующим сущности. Если вы планируете подвергать свой объект и уровень доступа к данным как api другим разработчикам, большая часть проверки должна выполняться на этом уровне.

Ответ 3

Должен ли я создавать DTO? существует ли какой-либо вред в экспонировании объектов непосредственно клиентам wcf.

  • Вы должны создать DTO. Когда объекты подвергаются воздействию DataContract, WCF создает эти сущности из любого мусора, который клиент может отправить на сервер. Плохая практика создания сущностей с недопустимым/несогласованным состоянием, даже если вы планируете проверить состояние позже.

Если я выставляю DTO, должен ли я проверять DTO, а также Entity. Если я проверяю только DTO, то я не предоставляю никаких входных проверок для моего объекта Enitity. это нормально?

  • Вы должны проверить DTO независимо от того, проверяете ли вы сущности или нет. Как уже говорилось, DTO содержат любой мусор от клиента. Ответственность уровня сервиса за проверку каждого параметра параметра метода сервиса и вызов базового уровня домена с использованием только правильных значений.

  • Хорошо удалить проверку с сущностей, если вы обязательно сделаете все проверки данных перед доступом к объектам.