views:

1035

answers:

4

Hello, I am learning DDD and I am a little bit lost in Infrastructure layer:

As I understand, "all good DDD applications" should have 4 layers: Presentation, Application, Domain and Infrastructure. Database should be accessed using Repositories. Repository interfaces should be in Domain layer and repository implementation - in Infrastructure (reference http://stackoverflow.com/questions/693221/ddd-where-to-keep-domain-interfaces-the-infrastructure).

Application, Domain and Infrastructure layer should/may have services (reference www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/21/services-in-domain-driven-design.aspx), in example EmailService in Infrastructure layer which sends Email messages.

BUT, inside Infrastructure layer we have repository implementations, which are used to access database. So, in this case, repositories are database services? What is the difference between Infrastructure service and repository?

Thanks in advance!

+3  A: 

An unfortunate thing about DDD is the word 'Service'. What it should be is 'Domain Service'. Think of the Domain as entities and value objects, while Services are a way of dealing with actions, operations and activities.

As for the Repositories, they are just a facade that should behave like a collection to your domain. If you are using an ORM or writing your own, this is what all your domain objects should be going through in order to achieve persistence instead of those services directly.

Ty
Well, maybe you misunderstood my question, or I misunderstood the answer. Inside infrastructure layer, if we have a service which deals with Mail API, we call it "email service", but the code to retrieve data from database is called "repository implementation". Isn't it the same type of "infrastructure service"?
Zygimantas
+1  A: 

Why would you put repository implementations into Infrastructure ? They're not related to 'Infrastructure' at all imho. I mostly put the repository interfaces into the 'domain model', and I put the implementation of those repositories the domain model as well.

Infrastructure should contain 'infrastructure' code, which could be a service which enables you to easily sent e-mail over smtp, or code which abstracts DB access for you (so, some classes that you could use in your repository, but it is not your repository).

So, do not put your repositories into 'infrastructure', since they do not belong there. To me, the classes that can be found in infrastructure , are classes that you can use in different other projects, see what I mean ? Classes that are not tightly related to your domain model or application belong in Infrastructure. And a repository implementation is quite tightly coupled to a specific application. :)

Frederik Gheysels
I see repositories as domain-specific, not necessarily application-specific. Looking at it that way, it makes sense to have a repository interface defined in your Domain Model layer. I see data access as a domain-specific infrastructure concern, separate from application code. I see what you're saying about reusable libraries, but I separate those libraries into different modules: one (or more) reusable modules, containing classes such as EmailSender, and one (or more) domain-specific infrastructure modules, containing classes such as CustomerRepository. Different modules, same layer.
Kevin Swiber
Indeed, repository implementation should not be in the application. It should be in the domain model.However, the application-layer should control the transaction-scope that is used by a repository.
Frederik Gheysels
A: 

Sticking with DDD definitions, a Repository is different than a Service. A Repository directly correlates to an Entity, often an Aggregate Root. A Service defines behaviors that don't really belong to a single Entity in your domain. You can absolutely find Services in every layer, though the types of problems they address differ from layer to layer and may be different from DDD's conceptual Service.

When working at the conceptual level, a DDD Repository differs from a DDD service in that it is specifically tied to Entity persistence. A Service can address any Domain, Application, or Infrastructure problem you may have.

You run into terminology clashes with DDD all over the place. For instance, a DDD Repository is NOT the same thing as the Repository pattern found in Martin Fowler's PoEAA book, though it may employ such a pattern. This is often a source of confusion for many people.

It helps with DDD if you always keep the Domain Model at the very center of everything you do. When it comes to layering DDD apps, I often choose Jeffrey Palermo's Onion Architecture. Check it out. Download CodeCampServer, an example app using this architecture. I think it's a perfect fit for DDD programming.

Good luck!

Kevin Swiber
+2  A: 

Maybe it will help to see a potential project structure.

Possible assembly or package structure:

Project.Domain
Project.Infrastructure.Data
Project.Infrastructure.Components
Project.Infrastructure.Services

Possible namespace or folder structure:

Project.Domain
-n- Modules
----n- Account
-------f- Account.xx
-------f- AccountRepository.xx
-------f- Contact.xx
----n- Marketing
-------f- RegionRepository.xx
-n- Shared
-n- Services

Project.Infrastructure.Data (OR-Mappers)
-n- Tables
-n- Views
-n- Procedures
-n- Functions

Project.Infrastructure.Components (Generic)
-n- Mail
-n- Cryptography
-n- UI

Project.Infrastructure.Services (Special Operatoins)
-f- DoingSomethingService1.xx
-f- DoingSomethingService2.xx
-f- DoingSomethingService3.xx

Domain Entities and Value Types do not use Domain Services. The Application Layer uses the Services of the Domain. The Domain Repository objects use the Infrastructure.Data objects to return Domain objects.

Roy Oliver
The point of DDD is not to have a certain project structure, but rather to have behavior on your entities. When you say "make copies of your ORM objects" it sounds like you're using an anemic domain, which is not really DDD at all. The behavior (domain state mutations) should be inside of the domain objects, not in services.
Ryan
Of course, Ryan. DDD is NOT about a certain project type. That's an implementation detail. That's why I said it may help to see a project structure. By "make copies", I'm speaking in context of attributes, NOT the behavior. Domain object will resemble database object, for the most part. What does that mean? It means that the attributes will be similar except for the Aggreate and Composition associations. Since that confused you, I'll remove that text. If it confused you, I'm sure it will confuse others.
Roy Oliver
I think you mean properties, not attributes. I don't mean to criticize, just to clarify. I'm of the school of thought that properties on a domain object are an anti-pattern. Lately I've been going towards a quasi-cqrs route: read only properties on my domain and methods to mutate state. My views are about 50% reading from denormalized DB views and 50% projecting off the domain model. The approach I choose just depends on the complexity of the data.
Ryan
@Roy since you said "Domain Entities and Value Types do not use Domain Services" does it mean it also do not use Repository?How about Aggregates, does it also not using Service nor Repository?
No Body
In the past, I had Entities or Aggregate Roots (AR) calling Repositories. Now, my AR are either saved or retrieved by Repositories. The Domain can be a very funny thing. You have to be comfortable with it's design and implementation. Some ARs are simple, yet some may have collection-properties that contain millions of items. It will often be too tempting to call a repository from an Entity or AR because sometimes it seems natural. I recommend try seeing how far you can get by not calling a Repository from an Entity or AR. What type of project or solution are you working on?
Roy Oliver
No Body
Roy Oliver
Roy Oliver
@No Body, See http://stackoverflow.com/questions/1584105/can-aggregate-root-entity-calls-repository/3071378#3071378
Roy Oliver