(Si vous n'avez pas envie de lire, il y a un résumé en bas :-)
Moi aussi, j'ai eu du mal avec la définition précise des services d'application. Bien que la réponse de Vijay ait été très utile à mon processus de réflexion il y a un mois, je suis en désaccord avec une partie de celle-ci.
Autres ressources
Il y a très peu d'informations sur les services d'application. Des sujets tels que les racines agrégées, les référentiels et les services de domaine sont abordés en détail, mais les services d'application ne sont mentionnés que brièvement ou sont complètement exclus.
L'article MSDN Magazine An Introduction To Domain-Driven Design décrit les services d'application comme un moyen de transformer et / ou d'exposer votre modèle de domaine à des clients externes, par exemple en tant que service WCF. C'est ainsi que Vijay décrit également les services d'application. De ce point de vue, les services applicatifs sont une interface avec votre domaine .
Les articles de Jeffrey Palermo sur l'architecture de l'oignon ( première , deuxième et troisième parties ) sont une bonne lecture. Il traite les services d' application comme des concepts au niveau de l' application , comme une session utilisateur. Bien que cela soit plus proche de ma compréhension des services d'application, cela ne correspond toujours pas à mes réflexions sur le sujet.
Mes pensées
J'en suis venu à considérer les services d'application comme des dépendances fournies par l'application . Dans ce cas, l'application peut être une application de bureau ou un service WCF.
Domaine
Temps pour un exemple. Vous commencez avec votre domaine. Toutes les entités et tous les services de domaine qui ne dépendent pas de ressources externes sont implémentés ici. Tous les concepts de domaine qui dépendent de ressources externes sont définis par une interface. Voici une disposition de solution possible (nom du projet en gras):
Ma solution
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Produit
ProductFactory
IProductRepository
Les classes Product
et ProductFactory
ont été implémentées dans l'assembly de base. C'est IProductRepository
quelque chose qui est probablement soutenu par une base de données. La mise en œuvre de ceci n'est pas du ressort du domaine et est donc définie par une interface.
Pour l'instant, nous allons nous concentrer sur le IExchangeRateService
. La logique métier de ce service est implémentée par un service Web externe. Cependant, son concept fait toujours partie du domaine et est représenté par cette interface.
Infrastructure
L'implémentation des dépendances externes fait partie de l'infrastructure de l'application:
Ma solution
+ My.Product.Core (My.Product.dll)
- My.Product.Infrastructure (My.Product.Infrastructure.dll)
- DomainServices
XEExchangeRateService
SqlServerProductRepository
XEExchangeRateService
implémente le IExchangeRateService
service de domaine en communiquant avec xe.com . Cette implémentation peut être utilisée par vos applications qui utilisent votre modèle de domaine, en incluant l'assembly d'infrastructure.
Application
Notez que je n'ai pas encore mentionné les services d'application. Nous allons les regarder maintenant. Disons que nous voulons fournir une IExchangeRateService
implémentation qui utilise un cache pour des recherches rapides. Le plan de cette classe de décorateur pourrait ressembler à ceci.
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.
}
Remarquez le ICache
paramètre? Ce concept ne fait pas partie de notre domaine, il ne s'agit donc pas d'un service de domaine. C'est un service d'application . C'est une dépendance de notre infrastructure qui peut être fournie par l'application. Introduisons une application qui le démontre:
Ma solution
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Produit
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
Tout cela se réunit dans l'application comme ceci:
// 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);
Résumé
Une application complète se compose de trois couches principales:
- domaine
- Infrastructure
- application
La couche de domaine contient les entités de domaine et les services de domaine autonomes. Tous les concepts de domaine (cela inclut les services de domaine, mais aussi les référentiels) qui dépendent de ressources externes, sont définis par des interfaces.
La couche infrastructure contient l'implémentation des interfaces à partir de la couche domaine. Ces implémentations peuvent introduire de nouvelles dépendances hors domaine qui doivent être fournies à l'application. Ce sont les services d'application et sont représentés par des interfaces.
La couche application contient l'implémentation des services d'application. La couche application peut également contenir des implémentations supplémentaires d'interfaces de domaine, si les implémentations fournies par la couche infrastructure ne sont pas suffisantes.
Bien que cette perspective puisse ne pas correspondre à la définition DDD générale des services, elle sépare le domaine de l'application et vous permet de partager l'assemblage de domaine (et d'infrastructure) entre plusieurs applications.