22

I am getting my feet wet with DDD (in .Net) for the first time, as I am re-architecting some core components of a legacy enterprise application.

Something I want to clear up is, how do we implement persistence in a proper DDD architecture?

I realize that the domains themselves are persistence ignorant, and should be designed using the "ubiquitous language" and certainly not forced into the constraints of the DAC of the month or even the physical database.

Am I correct that the Repository Interfaces live within the Domain assembly, but the Respository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?

Where are my actual repository methods (CRUD) being called from?

Benjamin Peter
  • 4,009
  • 2
  • 23
  • 23
EkoostikMartin
  • 6,831
  • 2
  • 33
  • 62
  • What does the `DAC` acronym stand for? And what do you mean by `Domain assembly`? Is it the domain aggregate/entity? Thank you. – tonix Jul 08 '20 at 07:53

3 Answers3

16

Am I correct that the Repository Interfaces live within the Domain assembly, but the Repository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?

Yes, this is a very good approach.

Where are my actual repository methods (CRUD) being called from?

It might be a good idea to not think in CRUD terms because it is too data-centric and may lead you into Generic Repository Trap. Repository helps to manage middle and the end of life for domain objects. Factories are often responsible for beginning. Keep in mind that when the object is restored from the database it is in its midlife stage from DDD perspective. This is how the code can look like:

// beginning 
Customer preferredCustomer = CustomerFactory.CreatePreferred();
customersRepository.Add(preferredCustomer);

// middle life
IList<Customer> valuedCustomers = customersRepository.FindPrefered();

// end life
customersRepository.Archive(customer);

You can call this code directly from you application. It maybe worth downloading and looking at Evan's DDD Sample. Unit of Work pattern is usually employed to deal with transactions and abstracting your ORM of choice.

dampee
  • 3,392
  • 1
  • 21
  • 37
Dmitry
  • 17,078
  • 2
  • 44
  • 70
  • 3
    I agree with everything Dmitry has said here, the only thing I'd add for clarity is that I'd recommend your client/UI project references an 'Application Services' layer, that invokes methods on the domain (either domain aggregates or domain services) and calls the repositories from here. This way all logic is contained within this application service, and you can change / add user interfaces with little effort. – David Masters Aug 24 '11 at 08:11
  • 1
    I would only add a service layer when it has clear benefits for the application, not just for the sake of it. A service layer is an extra layer of abstraction which in many cases you can do without. – Robin van der Knaap Aug 25 '11 at 23:53
  • @RobinvanderKnaap, that's not true, Application Services layer is required at all times, in real-world software development situation. If you hand the UI dev team the domain layer, it may a) not know how to use it, b) may misuse it. You need to be explicit about what the UI can do with your Business API (Domain Layer). – hyankov Oct 29 '17 at 17:16
  • `The persistence layer contains a reference to the Domain layer, never vice versa?` Does this mean that the persistence layer contains implementations of the repository interface and this concrete implementations in turn create concrete domain aggregates/entities e.g. using factories? Thank you! – tonix Jul 08 '20 at 08:16
5

Check out what Steve Bohlen has to say on the subject. The code for the presentation can be found here.

I was at the presentation and found the information on how to model repositories good.

Jesse C. Slicer
  • 19,901
  • 3
  • 68
  • 87
  • 1
    Very nice, definitely the most straight forward introduction to DDD I've seen. The code is nice because it isn't bogged down with fancy plumbing like many of the other examples out there. Unfortunately it is a little light on the actual implimentation side of things, which I was really trying to get help on. – EkoostikMartin Aug 23 '11 at 18:54
-1

Am I correct that the Repository Interfaces live within the Domain assembly, but the Repository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?

I disagree here, let's say a system is comprised of the following layers:

  • Presentation Layer (win forms, web forms, asp.net MVC, WPF, php, qt, java, , ios, android, etc.)
  • Business Layer (sometimes called managers or services, logic goes here)
  • Resource Access Layer (manually or ORM)
  • Resource/Storage (RDBMS, NoSQL, etc.)

The assumption here is that the higher you are the more volatile the layer is (highest being presentation and lowest being resource/storage). It is because of this that you don't want the resource access layer referencing the business layer, it is the other way around! The business layer references the resource access layer, you call DOWN not UP!

You put the interfaces/contracts in their own assembly instead, they have no purpose in the business layer at all.

Alex
  • 2,247
  • 1
  • 27
  • 37
  • Alex while you make a very good point. I feel the question is specifically about implementing in a pure DDD application. When we generally think of 3 Tier applications we think about each tier only accessing the layer below it. While in DDD your Domain comprises of multiple layers that talk to each other and as the Core Domain needs to be persistence ignorant hence it is always referenced by Repository/Infrastructure layer and not vice versa, – Afraz Ali Aug 13 '18 at 05:28