(Если вам не хочется читать, внизу есть сводка: -)
Я тоже боролся с точным определением сервисов приложений. Хотя ответ Виджая был очень полезен для моего мышления месяц назад, я пришел к тому, что не согласен с его частью.
Другие ресурсы
Информации об услугах приложений очень мало. Такие темы, как совокупные корни, репозитории и доменные сервисы, широко обсуждаются, но сервисы приложений упоминаются лишь кратко или вообще не упоминаются.
В статье MSDN Magazine Введение в доменно-управляемый дизайн описывает службы приложений как способ преобразования и / или представления модели вашего домена для внешних клиентов, например, как сервис WCF. Так Vijay описывает сервисы приложений. С этой точки зрения сервисы приложений представляют собой интерфейс вашего домена .
Статьи Джеффри Палермо об Луковой архитектуре (часть один , два и три ) - хорошее чтение. Он рассматривает службы приложений как концепции уровня приложения , такие как сеанс пользователя. Хотя это ближе к моему пониманию служб приложений, оно все еще не соответствует моим мыслям по этому вопросу.
Мои мысли
Я начал думать о службах приложений как о зависимостях, предоставляемых приложением . В этом случае приложение может быть настольным приложением или службой WCF.
Домен
Время для примера. Вы начинаете с вашего домена. Здесь реализованы все сущности и любые доменные сервисы, которые не зависят от внешних ресурсов. Любые доменные понятия, которые зависят от внешних ресурсов, определяются интерфейсом. Вот возможный макет решения (название проекта выделено жирным шрифтом):
My Solution
- <b>My.Product.Core</b> (My.Product.dll)
- DomainServices
IExchangeRateService
Product
ProductFactory
IProductRepository
Классы Product
и ProductFactory
были реализованы в базовой сборке. IProductRepository
- это то, что, вероятно, поддерживается базой данных. Реализация этого не относится к области и поэтому определяется интерфейсом.
Пока мы сосредоточимся на IExchangeRateService
. Бизнес-логика для этого сервиса реализуется внешним веб-сервисом. Однако его концепция все еще является частью домена и представлена этим интерфейсом.
Инфраструктура
Реализация внешних зависимостей является частью инфраструктуры приложения:
My Solution
+ <b>My.Product.Core</b> (My.Product.dll)
- <b>My.Product.Infrastructure</b> (My.Product.Infrastructure.dll)
- DomainServices
XEExchangeRateService
SqlServerProductRepository
XEExchangeRateService
реализует службу домена IExchangeRateService
, связываясь с xe.com . Эта реализация может использоваться вашими приложениями, использующими модель вашего домена, включая сборку инфраструктуры.
Применение
Обратите внимание, что я еще не упомянул службы приложений. Мы посмотрим на них сейчас. Допустим, мы хотим предоставить реализацию IExchangeRateService
, которая использует кэш для быстрого поиска. Контур этого класса декоратора может выглядеть следующим образом.
public class CachingExchangeRateService : IExchangeRateService
{
private IExchangeRateService service;
private ICache cache;
public CachingExchangeRateService(IExchangeRateService service, ICache cache)
{
this.service = service;
this.cache = cache;
}
// Implementation that utilizes the provided service and cache.
}
Обратите внимание на параметр ICache
? Эта концепция не является частью нашего домена, поэтому это не служба домена. Это служба приложений . Это зависимость нашей инфраструктуры, которая может быть предоставлена приложением. Давайте представим приложение, которое демонстрирует это:
My Solution
- <b>My.Product.Core</b> (My.Product.dll)
- DomainServices
IExchangeRateService
Product
ProductFactory
IProductRepository
- <b>My.Product.Infrastructure</b> (My.Product.Infrastructure.dll)
- ApplicationServices
ICache
- DomainServices
CachingExchangeRateService
XEExchangeRateService
SqlServerProductRepository
- <b>My.Product.WcfService</b> (My.Product.WcfService.dll)
- ApplicationServices
MemcachedCache
IMyWcfService.cs
+ MyWcfService.svc
+ Web.config
Все это объединяется в приложении следующим образом:
// Set up all the dependencies and register them in the IoC container.
var service = new XEExchangeRateService();
var cache = new MemcachedCache();
var cachingService = new CachingExchangeRateService(service, cache);
ServiceLocator.For<IExchangeRateService>().Use(cachingService);
Резюме
Полное приложение состоит из трех основных слоев:
- домен
- инфраструктура
- применение
Доменный уровень содержит доменные объекты и автономные доменные службы. Любые домены понятия (включая доменные службы, но также и репозитории), которые зависят от внешних ресурсов, определяются интерфейсами.
Уровень инфраструктуры содержит реализацию интерфейсов из уровня домена. Эти реализации могут вводить новые не доменные зависимости, которые должны быть предоставлены приложению. Это службы приложений и представлены интерфейсами.
Прикладной уровень содержит реализацию прикладных сервисов. Прикладной уровень также может содержать дополнительные реализации доменных интерфейсов, если реализации, предоставляемые инфраструктурным уровнем, недостаточны.
Хотя эта перспектива может не совпадать с общим определением служб DDD, она отделяет домен от приложения и позволяет совместно использовать сборку домена (и инфраструктуры) между несколькими приложениями.