DDD ( Domain Driven Design ), is a set of patterns, principles and practices that help us solve and understand business problems (Domain) in the design of object-oriented systems. DDD is a very broad topic.
I have been using the N - Layers architecture from Windows Forms but in ASP.NET MVC I have a doubt since I am a beginner working on web systems.
Let's focus on the DDD architecture.
Let's go straight to the problem I have. Starting from the domain entities are objects that have an identity and are important within the business logic of our application, but they do not have to be known directly by other layers of the application.
This is the structure of my project.
I am using DTOs or Data Transfer Objects are classes whose main objective is to simplify the objects that are going to be exchanged between processes.
In the Application Layer , in which I have two projects: Application Services and Adapters .
- Adapters: This is where I have implemented my DTOs.
- Application Services: It is in this layer where I implement the application methods, since my Presentation Layer is ignorant of the Domain Layer and vice versa. Returning to the subject, it is in this layer where I do the magic that the Domain Entities become DTOs through AutoMapper.
Domain Entities.
public class Proveedor
{
public int ProveedorId { get; set; }
public string RazonSocial { get; set; }
public string Direccion { get; set; }
}
DTO's
public class ProveedorDto
{
[Key]
public int ProveedorId { get; set; }
[Display(Name = "Razón Social")]
public string RazonSocial { get; set; }
[Display(Name = "Dirección")]
public string Direccion { get; set; }
}
Applying AutoMapper in Application Services.
public IEnumerable<ProveedorDto> GetAll()
{
IEnumerable<Proveedor> _proveedor = _sdProveedor.GetAll();
config = new MapperConfiguration(cfg => cfg.CreateMap<Proveedor, ProveedorDto>());
IEnumerable<ProveedorDto> listDto = config.CreateMapper().Map<IEnumerable<ProveedorDto>>(_proveedor);
return listDto;
}
In this way, my Domain Entities do not reach the Presentation Layer and the DTOs that are in the Adapters Layer are used as the Models of the MVC design pattern.
- Should I create the Models in the Presentation Layer, do I have to stick to the letter that the Models are implemented in that layer, as MVC says?
- How should I implement that part that I have explained, using good practices so that my architecture is neat?
I think it is important to be clear about the difference between theory and practice. Throughout the application you will find yourself in many situations that can force you to break that theory in pursuit of productivity and efficiency. It is up to you, as the architect of the application, to make that decision.
From my personal experience, models don't paint anything on the presentation layer. I started by having them in the persistence layer, which is their ideal place, to end up in a transversal layer called "Infrastructure", since one way or another, it was easy to end up needing their reference in other layers. In theory, everything related to persistence, models included, should be located in that layer. The domain should not have any relation to models or be aware of their existence.
If you are an architecture purist and are able to reduce the coupling between layers to zero, you will have reached the ideal architecture, but I insist that many times it is necessary to break those rules and do things with a head. When time passes and you have been working with the application for a long time, you will realize the things you have done well and the things you have done wrong.
Dude
In fact, the opposite is true, the entire application must know the domain. The idea behind DDD is to create a business model that is a black box that works and solves business problems.
So the focus is on creating an ecosystem where entities interact and collaborate.
To make it clearer, the concept would be something like: the sun with its own existence has an effect, its light, its gravity affects the planets, the climate, so should each event that occurs in the domain.
In your model that must happen if I have an accounting system and an invoice must enter when sending the message to the model it must validate, affect other entities and register if necessary or perhaps modify something.
All that logic is encapsulated in the domain in such a way that the operations are not typical:
_repisitorio.invoices.add(invoice)
but
model.Invoices.RegistrarFactura(invoice)
In generating all the logic, you encapsulate it in a domain capable of processing its own operations, which makes it very valuable.
It is also important to mention that a domain has nothing to do with persistence because it should be able to work without persistence even though a domain without persistence is almost useless.
Now the reason for using domain to user object transformations is because in mvc the results are done through a viewmodel and in a domain a concept can involve a kind of collaboration between business entities which doesn't make it a candidate to represent to the user.
for example you can have a purchase order and its items and the user from the ui is displayed the purchase order and the number of items, obviously this has to be processed and the result will fill a viewmodel ready to display
Another important concept is that by being focused on a Domain, we no longer talk about isolated concepts, for example before it was typical for something to have entities like
Emp is now Employee. Simple, right?
The entities must be common among all the people on the team, it is what is called Ubiquitous language, it can be said that colloquial language should not have abstractions as it used to happen before, but you should be able to talk with the business expert about the same concepts.
It is also important that to model the domain it is not born in your head, the domain of a business always already exists, what is done is to talk to those who know the business and then this is passed to the code, that is why it is important to understand well as it works if it is not possible that you leave empty and therefore cannot solve all the problems.
Check out Eric Evans' book, Domain Drive Design
False, they are seen at all levels but the user does not necessarily have to know them.
Should I create the Models in the Presentation Layer, do I have to stick to the letter that the Models are implemented in that layer, as MVC says?
As it is implemented in mvc it has nothing to do with ddd but an important point, the actions are closely related to a view model which, as its name says, is a model of the view, that is, of the page, which has nothing to do with your domain because its reason for being is the view or the page and this is a concept handled in mvc.
How should I implement that part that I have explained, using good practices so that my architecture is neat?
There is no recipe, you have to document yourself.
For the mvc pages, custom view models are used, which is a model designed for that web page and is filled with the data of the domain entities that are DTOs. You make a request to the business layer, which returns a domain object (dto) and you map it to your custom view model. In this way you create local models to your web pages to your liking that can be nourished by one or several domain objects.