I have a DTO that's managed by a Repository and in the end I want to map this DTO to a different type of object that's used by the Presentation layer.
Should the mapping happen in the Repository or in the domain layer? ( Use case/ Interactor)
In clean architecture the repository returns entities which are "used" bei the Interactors to implement the business rules. The Interactors return "response models" (DTOs) which are used by the presenters to generate "view models" which are used by the views to show results to the users.
Depending on the responsibility of ur "different type of object" the mapping would be in the Interactor or presenter.
U can find more details about Interactors and presenters in my blog post here: https://plainionist.github.io/Implementing-Clean-Architecture-Controller-Presenter/
I think the term DTO is a little too vague to answer this question. It really depends on what the purpose of the transformation is.
For example, let's assume we have some kind of system that has a Book object in its entities (in the domain layer). The book object returned by the repositories may have a field named pendingDelete because we delete books in a background task in batches. This field is needed by the domain layer but not externally and so, in the use case layer, we transform the book object into another object (maybe by casting to an interface or maybe creating a whole new object) that does not have this field. This meets the definition of a DTO in my brain and this mapping would happen in the domain layer.
Alternatively, lets now consider that we need to transform that object into a different object that has been decorated with various annotations/metadata that instruct how to serialize the object into XML or JSON. This also meets the definition of a DTO but this mapping would happen outside of the domain layer.
In the first example, we are using the DTO to control the interface to our inner layers and so we do that mapping in the inner layers. In the second example we are using the DTO to control the interface to our outer layers and so we do that mapping in the outer layers.
Usecase makes use of plugins. Plugins are abstraction over libraries (Gateway).
So in this case, a library (native or third party) will have to make an API call and get the json response, then convert it as a DTO object and hand it over to the usecase with the callback method. Then usecase can hand it over to presenter which will then convert it to respective view model.
Related
In DDD, your domain object's properties are mostly readonly from the outside. Now, in MVC, you'll typically get the object provided to you from the view or repository, but how do you go about this in Webforms, where you read the form inputs manually and apply them to the domain object? Do you create a DTO and give the domain object a Create method that takes the DTO?
The common pattern for recording an action or activity in a domain model, is to model the action as an object associated with the thing, people and places it interacts with.
So by example, if one had Orders associated with a Product, one would typically create the Order via an Order method on the applicable product. Data representing the Order captured via the UI would be passed to that Order method.
This represents the simple case for illustration purposes.
Do you create a DTO and give the domain object a Create method that takes the DTO?
No, you will typically have a piece in the middle, a message handler which is responsible for taking the DTO and converting it to values recognized by the domain. The domain objects have command methods that are used to update the state of the model.
So something like
Receive the DTO
Lookup the appropriate handler for that DTO
Parse the DTO, creating the value types recognized by the domain
Load the target aggregate from the repository
Invoke the command on the target, passing domain value types as arguments.
"Input validation" typically happens in step 3. "Business validation" typically happens on step 5.
A good approach is to make your domain entities always valid, always consistent. How you make them consistent right from creation is simply through the entity's constructor or a Factory that will check that the provided input is good enough to construct a valid entity.
Do you create a DTO and give the domain object a Create method that
takes the DTO?
The Domain layer doesn't have a dependency to other layers, so you can't reference an external DTO there. Entity constructors and Factories typically take primitive values or value objects (sometimes other entities) as an input, not DTO's.
After a comment of this question. I started to research but I am still confused.
Entities should convert to Dto before return to controller? To me it sounds not really practical.
We are talking about software architecture and as always when we are talking about software architecture there are a thousand ways of doing something and many opinions about what is the best way. But there is no best way, everything has advantages and disadvantages. Keep this in mind!
Typically you have different layers:
A persistence layer to store data
Business layer to operate on data
A presentation layer to expose data
Typically, each layer would use its own kind of objects:
Persistence Layer: Repositories, Entities
Business Layer: Services, Domain Objects
Presentation Layer: Controllers, DTOs
This means each layer would only work with its own objects and never ever pass them to another layer.
Why? Because you want each layer to be separated from the other layers. If you would use entities in your controller, your presentation would depend on how your data is stored. That's really bad. Your view has nothing to do with how the data is stored. It shouldn't even know that or how data is stored.
Think of that: You change your database model, e.g. you add a new column to one of your database tables. If you pass the entities to your controller (or worse: your controller exposes them as JSON), a change at the database would result in a change in your presentation. If the entities are directly exposed as JSON, this might even result in changes in JavaScript or some other clients which are using the JSON. So a simple change in the database might require a change in the JavaScript front end, because you couple your layers very tight. You definitely don't want that in a real project.
How? You doubt that this is practical, so just a small example of how to do that in (pseudo) code:
class Repository {
public Person loadById(Long id) {
PersonEntity entity = loadEntityById(id);
Person person = new Person();
person.setId(entity.getId());
person.setName(entity.getFirstName + " " + entity.getLastName());
return person;
}
}
In this example, your repository would use entities internally. No other layer knows or uses this entities! They are an implementation detail of this particular layer. So if the repository is asked to return a "person", it works on the entity, but it will return a domain object. So the domain layer which works with the repo is save in the case the entities need to be changed. And as you can see in the case of the name, the domain and the database might be different. While the database stores the name in first name and last name, the domain only know a single name. It's a detail of the persistence how it stores the name.
The same goes for controllers and DTOs, just another layer.
In this great book about Domain-Driven Design, a chapter is dedicated to the user interface and its relationship to domain objects.
One point that confuses me is the comparison between Use case optimal queries and presenters.
The excerpt dealing with optimal queries (page 517) is:
Rather than reading multiple whole Aggregate instances of various
types and then programmatically composing them into a single container
(DTO or DPO), you might instead use what is called a use case optimal
query.
This is where you design your Repository with finder query
methods that compose a custom object as a superset of one or more
Aggregate instances.
The query dynamically places the results into a
Value Object (6) specifically designed to address the needs of the use
case.
You design a Value Object, not a DTO, because the query is
domain specific, not application specific (as are DTOs). The custom
use case optimal Value Object is then consumed directly by the view
renderer.
Thus, the benefit of optimal queries is to directly provide a specific-to-view value object, acting as the real view model.
A page later, presenter pattern is described:
The presentation model acts as an Adapter. It masks the details of the
domain model by providing properties and behaviours that are designed
in terms of the needs of the view.
Rather than requiring the
domain model to specifically support the necessary view properties, it
is the responsibility of the Presentation Model to derive the
view-specific indicators and properties from the state of the domain
model.
It sounds that both ways achieve the construction of a view model, specific to the use case.
Currently my call chain (using Play Framework) looks like:
For queries: Controllers (acting as Rest interface sending Json) -> Queries (returning specific value object through optimal queries)
For commands: Controllers (acting as Rest interface sending Json) -> Application services (Commands) -> domain services/repositories/Aggregates (application services returns void)
My question is: if I already practice the use case optimal query, what would be the benefit of implementing the presenter pattern? Why bother with a presenter if one could always use optimal queries to satisfy the client needs directly?
I just think of one benefit of the presenter pattern: dealing with commands, not queries, thus providing to command some domain objects corresponding to the view models determined by the presenter. Controller would then be decoupled from domain object.
Indeed, another excerpt of Presenter description is:
Additionally, edits performed by the user are tracked by the
Presentation Model.
This is not the case of placing overloaded
responsibilities on the Presentation Model, since it's meant to adapt
in both directions, model to view and view to model.
However, I prefer sending pure primitives to application services (commands), rather than dealing directly with domain object, so this benefit would not apply for me.
Any explanation?
Just a guess :)
The preseneter pattern could reuse your repository's aggregate finder methods as much as possible. For example, we have two views, in this case we need two adapters(an adapter per view), but we only need one repository find method:
class CommentBriefViewAdapter {
private Comment comment;
public String getTitle() {
return partOf(comment.getTitle());
//return first 10 characters of the title, hide the rest
}
.....//other fields to display
}
class CommentDetailViewAdapter {
private Comment comment;
public String getTitle() {
return comment.getTitle();//return full title
}
.....//other fields to display
}
//In controller:
model.addAttribute(new CommentBriefViewAdapter(commentRepo.findBy(commentId)));
// same repo method
model.addAttribute(new CommentDetailViewAdapter(commentRepo.findBy(commentId)));
But optimal queries is view oriented(a query per view). I think these two solutions are designed for none-cqrs style ddd architecture. They're no longer needed in a cqrs-style arichitecture since queries are not based on repository but specific thin data layer.
In my app I have my domain layer and web interface (other layers I will not go into details).
My views, working with ViewModels objects, and the database persist domain objects.
To convert a ViewModel object to a domain object I use AutoMapper.
The problem with the working Breeze is that when I will create a new object var newCust = manager.createEntity('Customer', {name:'Beta'}) this is a domain object, and should be an ViewModel object.
Not all, but in some cases the ViewModel is not similar to the object domain. For example, collections of objects in the domain are: ICollection<Person> while in view model are ICollection<int> int is a PK of person.
Question
How to working with breeze in these cases?
How to make the metadata also manages the structure of my viewmodels so I can create objects of type my ViewModel?
#ridermansb - Because you mentioned AutoMapper, I will assume that your mapping is taking place on the server. You want your server API to expose "ViewModels" (in this case you might call them DTOs) rather than the domain model objects. Sometimes your ViewModels mirror your domain objects exactly; sometimes they don't.
Your client only sees what your API exposes. If this is a BreezeJS client, you will likely treat the ViewModels as client-side entities. They are Breeze entities in the sense that you expect Breeze to query, cache, change-track, and validate them. BreezeJS doesn't know whether these "entities" correspond to server-side DTOs or server-side business objects.
Of course if you're using DTOs/ViewModels, your server code is responsible for translating between the DTO form and the domain object form. Presumably this logic lies somewhere in/between the server-side API layer and the domain layer.
If you have chosen this architecture, you have chosen to deal with the bi-directional translation between ViewModels and domain objects and have embraced all the complexity and hassle that entails. I have no words of advice for you on that score.
So let me rephrase and narrow your question: "How can I get metadata that describe the object model exposed by my server-side API?"
My favorite way (assuming a .NET server) is to let EF do it for me. I create a DbContext that references NOT my domain model classes but rather my ViewModel/DTO classes. Of course these classes would not actually map to a real database. No problem; they don't have to. You will never use this DbContext to access data. You will only use it to generate metadata. You are using EF as a design-time, metadata-generating tool ... and that's it. This is an efficient maintainable approach.
I hope to demonstrate this technique "soon" but I've been mighty busy recently so no promises.
Alternatively, you can write the metadata by hand as described here.
This question really has larger architectural implications and I welcome any input or suggestions on this:
I'm more of the Martin Fowler school of thought when it comes to OOP. I believe you should be able to directly render domain entities in the UI. If I have a Car entity, I should be able to render it to a webpage. The domain model is a crosscutting concern and not a layer. Treating the domain model as a layer leads to an anemic domain model. I don't believe in DTOs in an OOP architecture.
A view model for me is a way of composing the domain entities required in your view. It's not a DTO. I don't understand what the reasoning behind using a view model like DTO is though it seems like a common thing to do using automapper?
So using the metadata approach I put data annotations on my domain model to give any UI implementation hints on how to render and validate the entities. I like to have a richER domain model.
In MVC3 how can you accomplish this (specifically using the Display data annotation) with a resource file that resides in the UI layer? Is there a native implementation for this or do I need to get creative myself? Or have I gone wrong somewhere in my approach?
I disagree.
For one thing, some of the attributes you will use to specify how an entity property should be displayed on a web page come from the System.Web namespace, not the System.ComponentModel.DataAnnotations namespace. By putting these attributes on properties in your domain model, your domain model is taking a dependency on System.Web. For example, there is the [HiddenInput] attribute that tells MVC3 to render a field as input type="hidden". This is not in System.CompoenentModel.DataAnnotations.
Secondly, I don't believe you need data annotation attributes on your entity properties to have a rich domain model. A rich domain model comes from classes that wrap knowledge in a context. The client application should not need to know anything about the domain in order to use it. You achieve a rich domain model with classes, methods, and properties that describe knowledge using the ubiquitous language. DataAnnotations attributes don't lend themselves well to the ubiquitous language imo. And, your domain is more than just your entities. There are factories, services, and other patterns that you can use to build a rich domain model. A domain with only entities and metadata sounds anemic to me.
Thirdly, you may have an entity that should be rendered in different ways on your web site. When someone searches for a car, you may want to display just the make, model, year, and thumbnail photo. When someone clicks on the search result, you may want to display multiple photos, reviews, etc. If you were to use the UIHint attribute on an entity to tell the web ui how to render the car, you wouldn't be able to have different strategies for rendering the Car in different contexts.
Finally, yes, automapper is really great for DTOing your entities into viewmodels. It essentially lets you populate copies of the entity, disconnected from the domain, targeted for specific UI concerns. Here it is safe to use HiddenInput and UIHint attributes to tell MVC3 how to render data.
Response to comment 1
As far as UIHint, I mentioned it here because it has a special meaning with MVC3 EditorTemplates. In cases where a partial view involves receiving input, what is the composition of the view? Text fields, drop-down lists, and input elements that often correspond to entities and their properties in some aggregate root. You will therefore need some representation of the entities to encapsulate the data. Your DTO can be an aggregate root as well, with depth. You can have a root DTO with scalar properties (text/date/bool), navigation properties (drop-down list) and collection properties (ul/ol/table).
We create a corresponding viewmodels for many entities in an aggregate root, and implement them as views using EditorTemplates. If we ever want to switch to a different EditorTemplate, we can apply UIHint to a viewmodel property. Thus we can tell it to "render a location dto as a google map". Automapper can map navigational and collection properties to corresponding viewmodels, forming as complex a representation of your domain entities as you need for the user.
Forgive me if I misunderstand what you mean by flat dto.
Response to comment 2
A viewmodel dto can flatten out / denormalize some properties (using automapper), if your requirements call for it. For example, consider a University entity. It may have many names in many languages (translations), hinting at a UniversityName entity in the aggregate, with University having a collection of Names (1..n). Of those names, 1 may represent the OfficialName / NativeName, and another may represent the TranslatedName to the user's CurrentUICulture. Other entities in the collection may represent TranslatedNames that the user does not understand, and need not be bothered with.
If you have a view that is only interested in these 2 Names in the collection, you can promote them to first-class properties on the viewmodel:
public class UniversityViewModel
{
public string OfficialName { get; set; }
public string TranslatedName { get; set; }
// ...other properties
}
This is a case where denormalizing part of the entity when converting to a viewmodel dto can make sense. Notice how the viewmodel is anemic -- a bare container for data transfer from a controller to a view. This is perfectly fine, and in fact, encouraged.
Answer to original question
To answer your original question, it helps if you think of your domain model & entities as a layer -- more specifically, a bottom layer. Layered software is easier to understand if you think about the various concerns in an application as having dependencies on other concerns. MVC3 is a presentation / UI layer, and will have dependencies on the layers beneath it -- one of those being your domain layer.
If you want to access a resource file in the UI from the domain layer, you are going in the opposite direction. You would be making a low layer depend on a higher layer. If your domain lib depends on the UI lib for a resource, and the UI lib depends on the domain for entities, you end up with a circular dependency. I think you could probably accomplish it using reflection if you needed to, but in that case, you would be fighting against the framework. MVC and .NET in general may not be the best choice for you if that is the case.
I actually think of resource files as a cross-cutting concern. Our application has i18n sprinkled throughout, and often we find we need the same language text resources in both the domain and the UI.
There is nothing wrong with putting a Display attribute on an entity. But if you want to use resources for it, then either put that resource in the domain layer, or if you feel it doesn't belong there, in a lower layer. That way it can be accessed by both the domain and the UI.
So I ended up putting a resourse file in the domain model and added a custom HiddenFieldAttribute so that I don't have to reference the MVC assembly in the domain model.
I still fundamentally dissagree that a view model is really a DTO and that the domain model should be constructed as a layer. I feel that architecting the application in this way creates abstractions that really have no value. If the domain model was truly a layer then we would build a set of logical interfaces from which to access it, and this we don't do. It's a cross cutting concern.
Thanks to olivehour for an interesting discussion and suggesting that it's okay to place resource file(s) in to domain model assembly.