3

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.

1
  • Repositories are part of Domain model. Repositories take and return domain entities. If repository is implemented using plain SQL or if it uses entities inside it is it's implementation detail.
    – Euphoric
    Sep 11 '16 at 11:23
2

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.

1

If you look at the CQRS pattern you'll note that domain operations boil down to commands. In this case I'd see it completely fine to define a delete command as just requiring the ID. Also using this pattern allows you complete flexibility in how the data is represented and does not tie one down to how the domain entities are structured.

Then there might be some cases where an operation against a domain would require it to be deleted. Say you have an email queue and an item reaches the send threshold. One could then argue that you can potentially check if the threshold was reached and just provide the object to the repository and have it be deleted that way.

One thing that I would be weary about would be to allow the controller to access the Domain objects directly.Ideally you'd rather have domain manipulations be done by the business layer and just have the Controllers (which should be responsible for UI rather) be able to communicate accordingly with the business layer.

0

You have some concepts need to clarify first before going further.

Let me get it for you, as those are the things I had scratched my head about.

  1. Controller (this is self explanation): the interface (maybe web view, desktop app view, mobile view, or API endpoints) of the application with external system, or user.

Controller need to pass data back and forth, this piece of data contains fields, somewhat like model's field. And we will call this piece of data is DTO (Data transfer object) or a simple object contains data for viewing.

  1. Repository (also self explanation): the data repository, where we can pull the data out of, or push the data into persistence (DB). This can be an ORM or simple interface to translate from model data into plain sql to work with database driver.

  2. (Business) Models and Services: This are the centric concepts of the system. They interact with each other, and work itself to solve all the business operation with the data that they contains.

For example:

  • CONTROLLER issue a command Delete(catalogId). The catalogId is a DTO.

  • SERVICES will validate the catalogId within the business scope of the infrastructure (make sure catalogId is good UUID, etc...) and then pull data out of REPOSITORY. The data pulled out from REPOSITORY will be constructed (may be constructed by a factory in either SERVICES or REPOSITORY) and return as a BUSINESS MODEL.

  • BUSINESS MODEL will validate the data with business domain concerns, like: is there any sub-catalog? is this catalog deleteable?... and if all validation pass, then BUSINESS MODEL will self-delete it or issue an event for the SERVICES to know that it's good to be deleted.

Notes: Self-delete sounds funny, but it works with the ORM. But I prefer the other option, there should be an object to manage all the domain, and clear its mess (if any).

  • Received the delete command, REPOSITORY will do it work to remove the persisted data and return the result (or not) to SERVICES.

  • SERVICES updated accordingly to CONTROLLER (with a DTO contains the deletion status).

After all, I think this is the ways that they work with each other. Maybe in some more complexity system, System Architect can design more layers, more object for better managing the state of the system. But minimal, I think that's enough.

Sorry for my English, I think it's not good. Please correct me if Iam wrong. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.