(Если вам не хочется читать, внизу есть резюме :-)
Я тоже боролся с точным определением сервисов приложений. Хотя ответ Виджая был очень полезен для моего процесса мышления месяц назад, я пришел к тому, что не согласен с его частью.
Другие источники
Там очень мало информации о сервисах приложений. Такие темы, как совокупные корни, репозитории и доменные сервисы, широко обсуждаются, но сервисы приложений упоминаются лишь кратко или вообще не упоминаются.
В статье MSDN Magazine «Введение в доменно-управляемый дизайн» описываются службы приложений как способ преобразования и / или представления модели вашего домена для внешних клиентов, например, как служба WCF. Так Vijay описывает сервисы приложений. С этой точки зрения сервисы приложений являются интерфейсом для вашего домена .
Статьи Джеффри Палермо об Луковой Архитектуре (часть первая , вторая и третья ) хорошо читаются. Он рассматривает службы приложений как понятия уровня приложения , такие как сеанс пользователя. Хотя это ближе к моему пониманию служб приложений, оно все еще не соответствует моим мыслям по этому вопросу.
Мои мысли
Я начал думать о службах приложений как о зависимостях, предоставляемых приложением . В этом случае приложение может быть настольным приложением или службой WCF.
Домен
Время для примера. Вы начинаете с вашего домена. Здесь реализованы все сущности и любые доменные сервисы, которые не зависят от внешних ресурсов. Любые доменные понятия, которые зависят от внешних ресурсов, определяются интерфейсом. Вот возможный макет решения (название проекта выделено жирным шрифтом):
Мое решение
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Товар
ProductFactory
IProductRepository
Product
И ProductFactory
классы были реализованы в базовой сборке. Это IProductRepository
то, что, вероятно, поддерживается базой данных. Реализация этого не относится к области и поэтому определяется интерфейсом.
Сейчас мы сосредоточимся на IExchangeRateService
. Бизнес-логика для этого сервиса реализуется внешним веб-сервисом. Однако его концепция все еще является частью домена и представлена этим интерфейсом.
инфраструктура
Реализация внешних зависимостей является частью инфраструктуры приложения:
Мое решение
+ My.Product.Core (My.Product.dll)
- My.Product.Infrastructure.dll (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.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Товар
ProductFactory
IProductRepository
- My.Product.Infrastructure.dll (My.Product.Infrastructure.dll)
- ApplicationServices
ICACHE
- DomainServices
CachingExchangeRateService
XEExchangeRateService
SqlServerProductRepository
- My.Product.WcfService (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, она отделяет домен от приложения и позволяет совместно использовать сборку домена (и инфраструктуры) между несколькими приложениями.