(Se você não quiser ler, há um resumo na parte inferior :-)
Eu também lutei com a definição precisa de serviços de aplicativos. Embora a resposta de Vijay tenha sido muito útil para o meu processo de pensamento há um mês, cheguei a discordar de parte dele.
Outros recursos
Há muito pouca informação sobre serviços de aplicativos. Assuntos como raízes agregadas, repositórios e serviços de domínio são discutidos extensivamente, mas os serviços de aplicativos são mencionados apenas brevemente ou são excluídos por completo.
O artigo da MSDN Magazine Uma Introdução ao Design Orientado a Domínio descreve os serviços de aplicativo como uma maneira de transformar e / ou expor seu modelo de domínio a clientes externos, por exemplo, como um serviço WCF. É assim que o Vijay também descreve os serviços de aplicativos. Desse ponto de vista, os serviços de aplicativos são uma interface para o seu domínio .
Os artigos de Jeffrey Palermo sobre a Onion Architecture (parte um , dois e três ) são uma boa leitura. Ele trata os serviços de aplicativo como conceitos no nível do aplicativo , como uma sessão do usuário. Embora isso esteja mais próximo da minha compreensão dos serviços de aplicativos, ainda não está alinhado com meus pensamentos sobre o assunto.
Meus pensamentos
Passei a pensar nos serviços de aplicativos como dependências fornecidas pelo aplicativo . Nesse caso, o aplicativo pode ser um aplicativo de desktop ou um serviço WCF.
Domínio
Hora de um exemplo. Você começa com o seu domínio. Todas as entidades e quaisquer serviços de domínio que não dependem de recursos externos são implementados aqui. Quaisquer conceitos de domínio que dependem de recursos externos são definidos por uma interface. Aqui está um layout de solução possível (nome do projeto em negrito):
Minha solução
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
produtos
ProductFactory
IProductRepository
As classes Product
e ProductFactory
foram implementadas na montagem principal. O IProductRepository
é algo que provavelmente é apoiada por um banco de dados. A implementação disso não é uma preocupação do domínio e, portanto, é definida por uma interface.
Por enquanto, vamos nos concentrar no IExchangeRateService
. A lógica de negócios para este serviço é implementada por um serviço da web externo. No entanto, seu conceito ainda faz parte do domínio e é representado por essa interface.
A infraestrutura
A implementação das dependências externas faz parte da infraestrutura do aplicativo:
Minha solução
+ My.Product.Core (My.Product.dll)
- My.Product.Infrastructure (My.Product.Infrastructure.dll)
- DomainServices
XEExchangeRateService
SqlServerProductRepository
XEExchangeRateService
implementa o IExchangeRateService
serviço de domínio comunicando-se com xe.com . Essa implementação pode ser usada por seus aplicativos que utilizam seu modelo de domínio, incluindo o conjunto da infraestrutura.
Inscrição
Observe que ainda não mencionei os serviços de aplicativos. Vamos ver isso agora. Digamos que queremos fornecer uma IExchangeRateService
implementação que use um cache para pesquisas rápidas. O esboço dessa classe de decorador pode ser assim.
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.
}
Observe o ICache
parâmetro? Esse conceito não faz parte do nosso domínio, portanto não é um serviço de domínio. É um serviço de aplicativo . É uma dependência de nossa infraestrutura que pode ser fornecida pelo aplicativo. Vamos apresentar um aplicativo que demonstra isso:
Minha solução
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
produtos
ProductFactory
IProductRepository
- My.Product.Infrastructure (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
Tudo isso se reúne no aplicativo como este:
// 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);
Resumo
Um aplicativo completo consiste em três camadas principais:
- domínio
- a infraestrutura
- inscrição
A camada de domínio contém as entidades de domínio e os serviços de domínio autônomo. Quaisquer conceitos de domínio (incluindo serviços de domínio, mas também repositórios) que dependem de recursos externos, são definidos por interfaces.
A camada de infraestrutura contém a implementação das interfaces da camada de domínio. Essas implementações podem introduzir novas dependências fora do domínio que precisam ser fornecidas ao aplicativo. Estes são os serviços de aplicativos e são representados por interfaces.
A camada de aplicativo contém a implementação dos serviços de aplicativo. A camada de aplicativo também pode conter implementações adicionais de interfaces de domínio, se as implementações fornecidas pela camada de infraestrutura não forem suficientes.
Embora essa perspectiva possa não corresponder à definição geral de serviços DDD, ela separa o domínio do aplicativo e permite compartilhar o conjunto de domínio (e infraestrutura) entre vários aplicativos.