Я разрабатываю трехуровневое приложение (не трехуровневое!) С клиентским приложением, работающим на одном уровне (физический кластер), которое взаимодействует с приложением-службой, работающим на другом уровне, и сервером базы данных на еще одном уровне. В приложении много бизнес-правил, логики процессов и т. Д., Которые, по моему мнению, должны быть доступны как на уровне приложений, так и на уровне служб, чтобы улучшить взаимодействие с пользователем, сократить количество обращений в службу, а также устранить избыточное кодирование.
Давайте использовать этот пример: в моем доменном слое у меня есть объект Document. Этот объект содержит свойство AllowPublish, которое проверяет внутреннее состояние объекта и возвращает истину / ложь, если состояние позволяет опубликовать документ. Объект также имеет метод Publish, который изменяет внутреннее состояние объекта, отражая тот факт, что он публикуется, устанавливая для флага IsPublished значение true и вызывая событие опубликованного домена.
У меня есть отдельный AuthorizationService, который определяет, разрешено ли текущему пользователю публиковать, а также DocumentRepository, который сохраняет объект в базе данных.
В моем сервисном приложении мой DocumentService имеет метод PublishDocument, который принимает идентификатор документа, извлекает документ из хранилища с использованием идентификатора, проверяет свойство AllowPublish и, если true, вызывает Publish, а затем сохраняет обновленный объект с использованием хранилища.
У меня немного другое поведение на клиенте. В этом случае я использую свойство AllowPublish для включения / выключения командных кнопок. При включении и нажатии я вызываю сервисный агент, который предоставляет метод PublishDocument, принимающий идентификатор документа. Агент передает вызов в одноименный метод DocumentService приложения-службы.
Чтобы исключить дублирование кода, поделиться бизнес-логикой, правилами проверки и т. Д. Я поместил объекты домена в отдельную сборку, совместно используемую как клиентским приложением, так и приложением-службой. Это означает, что клиентское приложение теперь имеет доступ к методу Publish моего класса Document, даже если оно является релевантным и должно использоваться только моим приложением-службой. Это заставляет меня пересмотреть весь подход, который я использую.
Хотя я понимаю использование DTO для передачи состояния между клиентом и сервером, я использую .NET 3.5 и, насколько мне известно, совместное использование сборки - это единственный способ поделиться бизнес-правилами и правилами проверки с клиентом. приложение. У меня есть некоторые идеи о том, в каких других направлениях я могу идти, но я надеялся получить некоторые предложения, прежде чем идти по новому пути.
С другой стороны, моя текущая реализация для клиента использует то, что я считаю цикличным подходом к авторизации, который может быть просто индикатором того, что другая модель будет лучше. Так же, как у меня есть AuthorizationService в моем приложении службы на стороне сервера, которое DocumentService использует для выполнения авторизации, у меня есть аналогичный агент, который использует мой клиентский код. Это означает, что мне нужен еще один уровень косвенности в моем клиентском коде для поддержки авторизации, возможно, Controller или ViewModel. Что хорошо, если вариант использования действителен.
EDIT
Может потребоваться уточнить, что свойство AllowPublish является динамическим при редактировании документа. При первом получении оно может быть ложным, но станет истинным, если деловые правила будут выполнены. Выполнение бизнес-правил в клиентском приложении позволяет нам расширить возможности пользователей.