Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD with EF Code First - how to put them together?

I am learning DDD development for few days, and i start to like it.

I (think i) understand the principle of DDD, where your main focus is on business objects, where you have aggregates, aggregates roots, repositories just for aggregates roots and so on.

I am trying to create a simple project where i combine DDD development with Code First approach.

My questions are: (I am using asp.net MVC)

  1. DDD Business Objects will be different than Code First objects? Even if they will probably be the same, for example i can have a Product business object which has all the rules and methods, and i can have a Product code first (POCO) object which will just contain the properties i need to save in database.

  2. If answer to question 1 is "true", then how do i notify the Product POCO object that a property from business object Product has been changed and i have to update it? I am using an "AutoMapper" or something like this? If the answer is "no", i am completely lost.

Can you show me the most simple (CRUD) example of how can i put those two together?

Thank you

like image 313
Catalin Avatar asked Nov 04 '12 12:11

Catalin


People also ask

Which EF approach can be used for domain driven design?

Advanced EF: Mapping DDD to EF Core. Domain Driven Design is a great way to start designing your applications. Entity Framework Core is a great framework to access and manipulate your data, stored in databases.

What is DDD programming?

Domain-driven design (DDD) is a software development philosophy centered around the domain, or sphere of knowledge, of those that use it. The approach enables the development of software that is focused on the complex requirements of those that need it and doesn't waste effort on anything unneeded.


1 Answers

Update I no longer advocate for the use of "domain objects" and instead advocate a use of a messaging-based domain model. See here for an example.

The answer to #1 is it depends. In any enterprise application, you're going to find 2 major categories of stuff in the domain:

Straight CRUD

There's no need for a domain object here because the next state of the object doesn't depend on the previous state of the object. It's all data and no behavior. In this case, it's ok to use the same class (i.e. an EF POCO) everywhere: editing, persisting, displaying.

An example of this is saving a billing address on an order:

public class BillingAddress {
  public Guid OrderId;
  public string StreetLine1;
  // etc.
}

On the other hand, we have...

State Machines

You need to have separate objects for domain behavior and state persistence (and a repository to do the work). The public interface on the domain object should almost always be all void methods and no public getters. An example of this would be order status:

public class Order { // this is the domain object  
  private Guid _id;
  private Status _status;

  // note the behavior here - we throw an exception if it's not a valid state transition
  public void Cancel() {  
    if (_status == Status.Shipped)
      throw new InvalidOperationException("Can't cancel order after shipping.")
    _status = Status.Cancelled;
  }

  // etc...
}

public class Data.Order { // this is the persistence (EF) class
  public Guid Id;
  public Status Status;
}

public interface IOrderRepository {
  // The implementation of this will:
  // 1. Load the EF class if it exists or new it up with the ID if it doesn't
  // 2. Map the domain class to the EF class
  // 3. Save the EF class to the DbContext.
  void Save(Order order); 
}

The answer to #2 is that the DbContext will automatically track changes to EF classes.

like image 88
Josh Kodroff Avatar answered Oct 03 '22 02:10

Josh Kodroff