C# – Architecture: How to pass models between controllers, services and repositories

cdomain-driven-designentity-frameworkonion-architectureorm

I'm trying to build an architecture where I have a Domain project with all my domain models, an Infrastructure project with my Services and Infrastructure.Entity with my Repositories and entities.

However, I'm a little confused on what's the best way to pass objects between the different layers.

The presentation layer only knows about the domain and service layer/infrastructure, and passes the domain objects to the service. And that's where I'm in doubt.

Let's say I have:

  • DomainProduct
  • EntityProduct
  • ProductController
  • ProductService
  • ProductRepository

Question:
Where do I map the objects between domain models and entities?
I call the service with a domain model, but does the service call the repository with a domain model, or do I map it to an entity and call the repository with that?

  1. Controller → Domain model → Service
  2. Service → Domain model → Repository

Or:

  1. Service → Entity → Repository

(and vice-versa)

Case: Deleting a product

Here I would just call the service from the controller with the ID of the product that needs to get deleted. Then the service either:

  • Calls Delete(id) on the repository

Or

  • Gets the product from the repository by the ID
  • Calls the delete method on the repository with the model?

However, isn't that a violation in DDD? Should I first get the DomainProduct from the service layer, and then call Delete with that DomainProduct? That just seems redundant an unnecessary.

I'm a little confused on how it's done best. I like the ID way the most, and passing entities between the service and repository. But I think it's a violation.

Best Answer

Ideally, you have separate domain models and data transfer objects (DTO). The domain model is a model per layer or domain. For example, the UI layer and the business logic layer should have their own domain objects.

You use DTO's to pass "data" between the layers.

[UI Layer] <- UserDto -> [Business logic layer]

The act of converting the domain objects to DTO's and back again on the other side is generally called "object mapping". Libraries like AutoMapper are used to simplify the process.