(Wenn Sie keine Lust zum Lesen haben, finden Sie unten eine Zusammenfassung :-)
Auch ich habe mit der genauen Definition von Anwendungsdiensten zu kämpfen. Obwohl Vijays Antwort vor einem Monat für meinen Denkprozess sehr hilfreich war, bin ich mit einem Teil davon nicht einverstanden.
Andere Ressourcen
Es gibt nur sehr wenige Informationen zu Anwendungsdiensten. Themen wie aggregierte Roots, Repositorys und Domänendienste werden ausführlich behandelt, Anwendungsdienste werden jedoch nur kurz erwähnt oder ganz weggelassen.
Der Artikel im MSDN-Magazin Eine Einführung in das domänengesteuerte Design beschreibt Anwendungsdienste als eine Möglichkeit, Ihr Domänenmodell zu transformieren und / oder externen Clients zur Verfügung zu stellen, z. B. als WCF-Dienst. So beschreibt Vijay auch Anwendungsdienste. Aus dieser Sicht sind Anwendungsdienste eine Schnittstelle zu Ihrer Domain .
Jeffrey Palermos Artikel über die Zwiebelarchitektur (Teil eins , zwei und drei ) sind eine gute Lektüre. Er behandelt Anwendungsdienste als Konzepte auf Anwendungsebene , z. B. als Benutzersitzung. Obwohl dies meinem Verständnis von Anwendungsdiensten näher kommt, entspricht es immer noch nicht meinen Gedanken zu diesem Thema.
Meine Gedanken
Ich stelle mir Anwendungsdienste als Abhängigkeiten vor, die von der Anwendung bereitgestellt werden . In diesem Fall kann die Anwendung eine Desktopanwendung oder ein WCF-Dienst sein.
Domain
Zeit für ein Beispiel. Sie beginnen mit Ihrer Domain. Hier werden alle Entitäten und Domänendienste implementiert, die nicht von externen Ressourcen abhängig sind. Alle Domänenkonzepte, die von externen Ressourcen abhängen, werden von einer Schnittstelle definiert. Hier ist ein mögliches Lösungslayout (Projektname fett gedruckt):
Meine Lösung
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Produkt
ProductFactory
IProductRepository
Die Klassen Product
und ProductFactory
wurden in der Kernassembly implementiert. Das IProductRepository
ist etwas, das wahrscheinlich von einer Datenbank unterstützt wird. Die Implementierung ist nicht das Anliegen der Domäne und wird daher durch eine Schnittstelle definiert.
Im Moment konzentrieren wir uns auf die IExchangeRateService
. Die Geschäftslogik für diesen Dienst wird von einem externen Webdienst implementiert. Das Konzept ist jedoch immer noch Teil der Domäne und wird durch diese Schnittstelle dargestellt.
Infrastruktur
Die Implementierung der externen Abhängigkeiten ist Teil der Infrastruktur der Anwendung:
Meine Lösung
+ My.Product.Core (My.Product.dll)
- My.Product.Infrastructure (My.Product.Infrastructure.dll)
- DomainServices
XEExchangeRateService
SqlServerProductRepository
XEExchangeRateService
implementiert den IExchangeRateService
Domänendienst durch Kommunikation mit xe.com . Diese Implementierung kann von Ihren Anwendungen verwendet werden, die Ihr Domänenmodell verwenden, einschließlich der Infrastrukturassembly.
Anwendung
Beachten Sie, dass ich Anwendungsdienste noch nicht erwähnt habe. Wir werden uns diese jetzt ansehen. Angenommen, wir möchten eine IExchangeRateService
Implementierung bereitstellen , die einen Cache für schnelle Suchvorgänge verwendet. Der Umriss dieser Dekorateurklasse könnte so aussehen.
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.
}
Beachten Sie den ICache
Parameter? Dieses Konzept ist nicht Teil unserer Domain, es ist also kein Domain-Service. Es ist ein Anwendungsdienst . Dies ist eine Abhängigkeit unserer Infrastruktur, die möglicherweise von der Anwendung bereitgestellt wird. Lassen Sie uns eine Anwendung vorstellen, die dies demonstriert:
Meine Lösung
- My.Product.Core (My.Product.dll)
- DomainServices
IExchangeRateService
Produkt
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
Dies alles kommt in der Anwendung wie folgt zusammen:
// 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);
Zusammenfassung
Eine vollständige Anwendung besteht aus drei Hauptschichten:
- Domain
- Infrastruktur
- Anwendung
Die Domänenschicht enthält die Domänenentitäten und eigenständigen Domänendienste. Jegliche Domain - Konzepte (einschließlich Domain - Services, sondern auch Repositories) , die auf externen Ressourcen abhängig sind , werden durch Schnittstellen definiert.
Die Infrastrukturschicht enthält die Implementierung der Schnittstellen aus der Domänenschicht. Diese Implementierungen können neue einführen Nicht-Domain - Abhängigkeiten, die die Anwendung zur Verfügung gestellt werden müssen. Dies sind die Anwendungsdienste und werden durch Schnittstellen dargestellt.
Die Anwendungsschicht enthält die Implementierung der Anwendungsdienste. Die Anwendungsschicht kann auch zusätzliche Implementierungen von Domänenschnittstellen enthalten, wenn die von der Infrastrukturschicht bereitgestellten Implementierungen nicht ausreichen.
Obwohl diese Perspektive möglicherweise nicht mit der allgemeinen DDD-Definition von Diensten übereinstimmt, trennt sie die Domäne von der Anwendung und ermöglicht es Ihnen, die Domänen- (und Infrastruktur-) Assembly für mehrere Anwendungen freizugeben.