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.
相关问题
- Shared common definitions across C/C++ (unmanaged)
- Aggregate to JPA Entity mapping
- Complex DTO structure
- Long-lived RESTful interactions
- How to make POCO work with Linq-to-SQL with comple
相关文章
- Can Persistence Ignorance Scale?
- DDD Domain Model Complex Validation
- Why doesn't there exists a subi opcode for MIP
- DDD Architecture - Where To Put Common Methods/Hel
- Proper scenekit architecture for multi level/scree
- MySQLi Error Handling?
- GET requests in TOR network without installing TOR
- TIme-based Notification Architecture
From the Red Book (Implementing Domain Driven Design, by Vaughn Vernon), this is how I understand the concepts:
Domain objects (entities and value objects) encapsulate behavior required by the (sub)domain, making it natural, expressive, and understandable.
Domain services encapsulate such behaviors that do not fit in a single domain object. For example, a book library lending a
Book
to aClient
(with correspondingInventory
changes) might do so from a domain service.Application services handle the flow of use cases, including any additional concerns needed on top of the domain's. It often exposes such methods through its API, for consumption by external clients. To build on our previous example, our application service might expose a method
LendBookToClient(Guid bookGuid, Guid clientGuid)
that:Client
.Book
.Client
andBook
) to handle the actual domain logic of lending the book to the client. For instance, I imagine that confirming the book's availability is definitely part of the domain logic.An application service should generally have a very simple flow. Complex application service flows often indicate that domain logic has leaked out of the domain.
As you can hopefully see, the domain model stays very clean this way, and is easy to understand and discuss with the domain experts, because it only contains its own, actual business concerns. The application flow, on the other hand, is also much easier to manage, since it is relieved of domain concerns, and becomes concise, and straightforward.
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:
(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, e.g. 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):
The
Product
andProductFactory
classes have been implemented in the core assembly. TheIProductRepository
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:
XEExchangeRateService
implements theIExchangeRateService
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.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:This all comes together in the application like this:
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.
Millett,C (2010). Professional ASP.NET Design Patterns. Wiley Publishing. 92.
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!
Domain service is the extension of the domain. It should be seen only in the context of the domain. This is not some user action like for instance close account or something. The domain service fits where there is no state. Otherwise it would be a domain object. Domain service does something which makes sense only when being done with other collaborators (domain objects or other services). And that making sense is the responsibility of another layer.
Application service is that layer which initializes and oversees interaction between the domain objects and services. The flow is generally like this: get domain object (or objects) from repository, execute an action and put it (them) back there (or not). It can do more - for instance it can check whether a domain object exists or not and throw exceptions accordingly. So it lets the user interact with the application (and this is probably where its name originates from) - by manipulating domain objects and services. Application services should generally represent all possible use cases. Probably the best thing you can do before thinking about the domain is to create application service interfaces what will give you a much better insight in what you're really trying to do. Having such knowledge enables you to focus on the domain.
Repositories can generally speaking be injected into domain services but this is rather rare scenario. It is the application layer who does it most of the time though.