Services in Domain-Driven Design

Services are first-class citizens of the domain model.  When concepts of the model would distort any Entity or Value Object, a Service is appropriate.  From Evans’ DDD, a good Service has these characteristics:

  • The operation relates to a domain concept that is not a natural part of an Entity or Value Object
  • The interface is defined in terms of other elements in the domain model
  • The operation is stateless

Services are always exposed as an interface, not for “swappability”, testability or the like, but to expose a set of cohesive operations in the form of a contract.  On a sidenote, it always bothered me when people say that an interface with one implementation is a design smell.  No, an interface is used to expose a contract.  Interfaces communicate design intent, far better than a class might.

But most examples I see of Services are something trivial, such as IEmailSender.  But Services exist in most layers of the DDD layered architecture:

  • Application
  • Domain
  • Infrastructure

An Infrastructure Service would be something like our IEmailSender, that communicates directly with external resources, such as the file system, registry, SMTP, database, etc.  Something like NHibernate would show up in the Infrastructure.

Domain services are the coordinators, allowing higher level functionality between many different smaller parts.  These would include things like OrderProcessor, ProductFinder, FundsTransferService, and so on.  Since Domain Services are first-class citizens of our domain model, their names and usages should be part of the Ubiquitous Language.  Meanings and responsibilities should make sense to the stakeholders or domain experts.

In many cases, the software we write is replacing or supplementing a human’s job, such as Order Processor, so it’s often we find inspiration in the existing business process for names and responsibilities.  Where an existing name doesn’t fit, we dive into the domain to try and surface a hidden concept with the domain expert, which might have existed but didn’t have a name.

Finally, we have Application Services.  In many cases, Application Services are the interface used by the outside world, where the outside world can’t communicate via our Entity objects, but may have other representations of them.  Application Services could map outside messages to internal operations and processes, communicating with services in the Domain and Infrastructure layers to provide cohesive operations for outside clients.  Messaging patterns tend to rule Application Services, as the other service layers don’t have a reference back out to the Application Services.  Business rules are not allowed in an Application Service, those belong in the Domain layer.

In top-down design, we typically start from the Application or Domain Service, defining the actual interface clients use, then use TDD to drive out the implementation.  As we’re always starting from the client perspective with actual client scenarios, we get a high degree of confidence that what we’re building will create success and add value.  When stories are vertical slices of functionality, this is fairly straightforward, at least mechanically so.

I used to make the mistake of dismissing Services as a necessary evil, confined to the Infrastructure layer.  Through more reading and conversation through our recent Austin DDD Book Club, I’ve started to realize the potential the Application and Domain services have in creating a well-designed model.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in DomainDrivenDesign. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Hi Jimmy,

    I’m way down the curve on DDD – I read Evans a long time ago, and I just read Nilsson’s book, but there’s still much I don’t understand due to limited experience with modelling a rich problem domain using DDD.

    One question I still have is: where is the right place to model cross-aggregate relationships? Are services an appropriate place?

  • Jimmy,

    I had a recent back-and-forth with Ayende on this topic on the back of the ALT.NET conference in Israel.

    This is the best link I have for that:

    My guidance is not to have classes in the domain model call services at all, preferring to raise an event (usually on a separate static class in the domain, say, DomainEvents). Classes external to the domain can subscribe to these events and do what needs to be done – like email.

    In many cases, the more general solution for this kind of logic is a saga.

    Hope that makes sense.

  • DDD Services are probably the most confused and discussed aspects of DDD. I see conversations popup on the mailing list frequently asking questions about services.

    I would say it depends on the context. If it makes sense to use a service to coordinate communication between aggregates because the required behavior doesn’t really fit in one aggregate or the other then a service would be appropriate.

    Another thing to note here is that Domain Services should only be working with instances of Entities/Value Objects in the domain, that is, you should already have the required objects from a Repository/Aggregate and provide them to the domain service. Having the Domain Service retrieve the objects from persistence storage is a smell, at least in my book. An application service however is different. I normally have application services communicate directly with repositories to complete their work if required.

    Jimmy, Do you find the same thing with your experience or do you handle it differently?

    I think the DDD community would be well served with more real world examples of Services in each context that would help communicate how people are actually using Services in their applications.

  • Roy

    If the Application Layer calls a Domain Service, then shouldn’t the Domain Service be a Static Class INSTEAD OF an Interface? I feel if a Domain Service is only an Interface, then that leaves the Application Layer with the responsibility to implement the business rules. I need clarification on this. This is the only aspect of DDD that confuses the hell out of me.


  • Pingback: Domain-Driven Design: Links, News, Resources (1) « Angel “Java” Lopez on Blog()

  • matt

    I have a question regarding the infrastructure layer. You said NHibernate belongs to the Infrastructure Layer, however NHibernate accepts Entities as parameters to persist, update etc. That means that the infrastructure layer knows about the domain layer which is a violation of the principle that lower layers are not to know about higher layers. 

    Sry, I guess this comment comes pretty late :-)  


    • I don’t think Infrastructure is the core layer – the domain layer is.

      • +1

        “Infrastructure” is a misleading term from a legacy worldview very different from DDD.  The only “infrastructure” under the domain layer is the language and the machine – the CLR/JVM/whatever.

    • cgitosh

      The infrastructure layer in this case would interact with the domain layer through repository interfaces, which are members of the domain layer. I.E The repository interfaces are declared within the domain layer but the implementation is done in the infrastructure layer. In onion architecture out layers (lower layer in your comment) can depend on layers more inward (higher layer) but inner layer can’t depend on outer layer…

  • Kelly Brownsberger

    Jimmy – what do you think of injecting services into the domain entities?

    I’ve long felt you can’t avoid having services and having them outside of my entities has always felt disjointed and non-cohesive… all the while I struggle to keep my domain rich.  This technique Fabio shows solves and makes the entities the focal point for domain behavior.

    I fear this fat-entity approach could have it’s own dragons.  Thoughts?

    • Anonymous

      Not a big fan, I still much prefer this pattern:
      Easier to reason about since the use of these services is contextual to specific operations.

      • Kelly Brownsberger

        Yeah… I remember that post and I tend to share your point of view.  However, I can also see the other point of view where now callers who may not know or care what the implementation of the balance calculator is must know and care.  While this approach is intention revealing in the sense that callers know something non-trivial is going to happen and something other than the current internal state of the domain object is needed, what if they don’t want to know?  I understand from a testing perspective have a blackbox behind each domain behavior can become a nightmare to test in isolation, but at the same time exposing these things to the caller can make their job more difficult too.  Callers now have to know how to construct them or go get them from somewhere (like a container).  I’m not sure that’s better.

        I’m just trying to dissect the pros and cons from all angles.  I can think of 3 or 4 ways to approach this, but none of them are without their respective cons.  Service injection seems like it could get out of hand and kill the simplicity of new’ing up POCO.  Do you have any links to horror stories of this approach?  Sounded like you have a long list of pitfalls in mind with this.  Would appreciate hearing any lessons you’ve learned there


        • Anonymous

          If someone is down in the weeds interacting directly with a domain object, but can’t supply what the dependency should be, why should this be pushed down to the ORM?

          Putting it another way – would you want the domain object interacting with a static helper class instead of an injected dependency, how is that any different?

  • Your fan

    Jimmy, a novice question, in your article you tell that application layer are those rom which outside world contacts, but when i was viewing ddd sample of eric evans , he specified one more layer, ie Interface layer, so all calls from my code behind pass through interface layer and then into application service layer. One more point if i want to write a wcf service so that, java guys can also consume my application functionalities how will i do that in ddd ?

    • That makes sense – although I don’t know why my code would need to pass through an interface layer. Why have a layer of indirection?

      For external clients that makes sense, although I would want to be careful not to fall into the trap of exposing capabilities through an RPC endpoint.

  • Thanks for this post. It cleared up some things on my mind. I had the dilemma of how I would name my service and the post helped me make things clear. 

    What did you mean by application services? Is this just your term for API like the one exposed by Twitter 

  • Pingback: Naming Your Services « Rockstar Engineering()

  • Pingback: CQRS & DDD – Domain Model Business Rules validation using cqrs read model | PHP Developer Resource()

  • Pingback: Which services are considered Infrastructure Services | Code and Programming()

  • it’s helpful and clear point post. Clear thought on Domain services.

    Domain lookup services also getting famous now

  • Slade Stewart

    Hey, I like this post. I found it for a different reason than one of your sidenotes, but since I’m also right now being a loudmouth to my colleagues about the ‘interface with only one implementation smell’, I thought I’d comment on that sidenote from your post.

    I just want to point out my perspective that first of all, given ‘the definition of a smell’, an interface with one implementation is exactly that: a smell i.e. a surface indication of **a potential** problem that warrants digging a little deeper. I’d say that what you’re saying is that there are cases where having an interface with only one implementation doesn’t represent anything wrong. I’d agree with that.

    I’d say that what **is** true is that if you follow the smell of an interface with one implementation and you find that it’s a Header Interface, it’s almost certainly not the right way to do things.

    To me there’s a subtle distinction: if a group has said “we can see that clients will have a need for IWhatever and we’re defining that interface. We are also going to build something that implements IWhatever and happens to have a one-to-one mapping. And right now and for the foreseeable future, this will be the only implementation”, that usually won’t bite anyone in the butt (it doesn’t necessarily represent cruft, etc.).

    However, by Header Interface I mean where it’s clear that the group has said “We’re building a Whatever. Let’s go ahead and define an IWhatever interface for it in case a client ever needs that interface.” That can have some negative consequences, ranging from cruft that gets in the way and slows things down (this is equivalent to Speculative Design or Speculative Generality), all the way to subtle circular reference situations that usually show themselves at an inopportune time and require significant teardown and rebuilding. One indication that this is what is happening is when the interface is defined in the same package as the/an implementation. One clear indication that this is wrong is ‘the inappropriate coupling’: that a consumer, in order to benefit from the interface, will have to also drag along those implementations via referential coupling.

    • jbogard

      Ah, thanks! I also like the idea of the single-implementation ones having names that reflect the implementation.