Domain Driven Design: Domain Service, Application Service
Can someone explain the difference between domain and application services by providing some examples? And, if a service is a domain service, would I put the actual implementation of this service within the domain assembly and if so, would I also inject repositories into that domain service? Some info would be really helpful.
Services come in 3 flavours: Domain Services , Application Services , and Infrastructure Services
Keeping Domain Services along with your Domain Objects is sensible - they are all focused on domain logic. And yes, you can inject Repositories into your Services.
Application Services will typically use both Domain Services and Repositories to deal with external requests.
Hope that helps!
(If you don't feel like reading, there's a summary at the bottom :-)
I too have struggled with the precise definition of application services. Although Vijay's answer was very helpful to my thinking process a month ago, I have come to disagree with part of it.
Other resources
There's very little information about application services. Subjects like aggregate roots, repositories and domain services are discussed extensively, but application services are only mentioned briefly or left out altogether.
The MSDN Magazine article An Introduction To Domain-Driven Design describes application services as a way to transform and/or expose your domain model to external clients, eg as a WCF service. This is how Vijay describes application services too. From this point of view, application services are an interface to your domain .
Jeffrey Palermo's articles on the Onion Architecture (part one, two and three) are a good read. He treats application services as application-level concepts , such as a user's session. Although this is closer to my understanding of application services, it's still not in line with my thoughts on the subject.
My thoughts
I have come to think of application services as dependencies provided by the application . In this case the application could be a desktop application or a WCF service.
Domain
Time for an example. You start out with your domain. All entities and any domain services that don't depend on external resources are implemented here. Any domain concepts that depend on external resources are defined by an interface. Here is a possible solution layout (project name in bold):
My Solution - My.Product.Core (My.Product.dll) - DomainServices IExchangeRateService Product ProductFactory IProductRepository
The Product
and ProductFactory
classes have been implemented in the core assembly. The IProductRepository
is something that is probably backed by a database. The implementation of this is not the domain's concern and is therefore defined by an interface.
For now, we'll focus on the IExchangeRateService
. The business logic for this service is implemented by an external web service. However, its concept is still part of the domain and is represented by this interface.
Infrastructure
The implementation of the external dependencies are part of the application's infrastructure:
My Solution + My.Product.Core (My.Product.dll) - My.Product.Infrastructure (My.Product.Infrastructure.dll) - DomainServices XEExchangeRateService SqlServerProductRepository
XEExchangeRateService
implements the IExchangeRateService
domain service by communicating with xe.com. This implementation can be used by your applications that utilize your domain model, by including the infrastructure assembly.
Application
Note that I haven't mentioned application services yet. We'll look at those now. Let's say we want to provide an IExchangeRateService
implementation that uses a cache for speedy lookups. The outline of this decorator class could look like this.
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.
}
Notice the ICache
parameter? This concept is not part of our domain, so it's not a domain service. It's an application service . It's a dependency of our infrastructure that may be provided by the application. Let's introduce an application that demonstrates this:
My Solution - My.Product.Core (My.Product.dll) - DomainServices IExchangeRateService Product 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
This all comes together in the application like this:
// 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);
Summary
A complete application consists of three major layers:
The domain layer contains the domain entities and stand-alone domain services. Any domain concepts (this includes domain services, but also repositories) that depend on external resources, are defined by interfaces.
The infrastructure layer contains the implementation of the interfaces from the domain layer. These implementations may introduce new non-domain dependencies that have to be provided the application. These are the application services and are represented by interfaces.
The application layer contains the implementation of the application services. The application layer may also contain additional implementations of domain interfaces, if the implementations provided by the infrastructure layer are not sufficient.
Although this perspective may not match with the general DDD definition of services, it does separate the domain from the application and allows you to share the domain (and infrastructure) assembly between several applications.
The best resource that helped me understand the difference between an Application Service and a Domain Service was the java implementation of Eric Evans' cargo example, found here. If you donwload it, you can check out the internals of RoutingService (a Domain Service) and the BookingService, CargoInspectionService (which are Application Services).
My 'aha' moment was triggered by two things:
Domain services are expressed in terms of the ubiquitous language and the domain types, ie the method arguments and the return values are proper domain classes.
What I find a big help in separating the apples from the oranges is thinking in terms of application workflow. All logic concerning the application workflow typically end up being Application Services factored into the Application Layer, whereas concepts from the domain that don't seem to fit as model objects end up forming one or more Domain Services.
链接地址: http://www.djcxy.com/p/26860.html上一篇: SQL(MySQL)与NoSQL(CouchDB)
下一篇: 域驱动设计:域服务,应用程序服务