Reputation: 479
It feels like I am referring to DDD topics of context mapping and anticorruption layer, but I am not sure how to address it.
How to construct/map domain objects from external data sources?
As an example there could be multiple data sources (db, files, external services). Since I am trying to build as similar to onion architecture as possible it means that my domain has no dependencies. Infrastructure depends on domain (specifically, infrastructure implements domain interfaces)
If infrastructure has to depend on domain (not vice versa), does it mean that external data mapping should be done within the repository?
How do you map external data to domain object if creating object via constructor is treated as business logic (which should not leak to anywhere but domain)? Reflection? Other ways? Maybe I am misunderstanding the whole concept?
If domain object creation requires data from multiple sources (services, file, db), does it mean that there should be a separate layer between application service and infrastructure (repository) that pulls the data from multiple repositories, does all the mapping and returns resulting domain object?
Upvotes: 0
Views: 914
Reputation: 19640
I prefer doing this via an explicit implementation of Anti-Corruption Layer. My domain usually accepts commands to do any operation, which is the domain model can accept. This includes creating objects and doing state transitions.
The ACL part reads from external data sources, or receives data from them by any other means. Then it converts this data to valid domain commands. All pre-checks are done via the ACL, which knows both about the external data formats and about the domain.
There are cases when one external event causes multiple operations in the domain or even multiple operations across multiple bounded contexts. Usually this is done by using process managers.
It could be, like you describe, multiple external data sources need to be queries to construct one valid domain command. In this case, the ACL just does that since there is only one transaction in the domain. It might get more complex in case when external sources also need to get a confirmation of some kind, process manager can be useful for that purpose as well.
Upvotes: 0
Reputation: 57279
How to construct/map domain objects from external data sources?
There are two approaches that I know of.
The most common is that the application communicates with the domain model via a common understanding of values. The application takes the representation that it has (for example, bytes in a file), and builds from it a representation that the domain model will understand. You might see this done via a factory (that understands how to convert primitive values to a value type) or a builder.
The rarer approach is that the application takes the representation that it has, and wraps it in an adapter that the domain model will recognize (as opposed to building a concrete type). In this style, value types look more like role interfaces, keeping the domain model ignorant of the underlying data model.
If domain object creation requires data from multiple sources (services, file, db), does it mean that there should be a separate layer between application service and infrastructure (repository) that pulls the data from multiple repositories, does all the mapping and returns resulting domain object?
I would expect the repository to be doing that work itself - the role of the repository is the abstraction of a key-value store.
We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.
The choice of services/files/db is one example of a decision that should be hidden within a module (the repository) whose interface "was chosen to reveal as little as possible about its inner workings".
Upvotes: 1