
Domain is the most important layer in your application. This layer reflects processes, calculations, and business rules. It is thanks to this logic that the business makes money, this logic makes it unique and allows it to stay ahead of the competition.

Based on a picture from Uncle Bob. You can imagine that the “Domain Layer” is the heart of the application, the other layers depend on it (note the arrows). However, it itself is not dependent on any of the layers (Note the absence of arrows).
Bussiness change resistant
As the domain layer is the heart of the system, we should design it so that it is resistant to changes, it is not about code modifications, it is about business changes.
When we work with the financial industry, our business rules are often governed by the law. What if the government suddenly changes these laws, your rules will also have to be changed because otherwise the system will become useless. Another example may be a situation when the business is still immature and only on the basis of feedback from customers, business rules will be changed.
The heart of our system will live with business, if it grows, the domain will evolve.
The designed IT system reflects the knowledge developer about the domain
Good practices for a domain layer
No dependencies, no frameworks – The code in the domain layer is a unique, pure model of business objects, so there is no need to install frameworks or references to other projects there. For example, if your project uses reference to ORM in the domain layer that is a leak of infrastructure to the domain and can decrease maintainability.
Ubiquitous language – we should use exactly the same expression that the business uses, which can be heard in meetings with the client. A business expert, after seeing our test names or class names, should know more or less what they are about, not knowing the programming language, but knowing the language of their industry.
Rich model design over anemic model design – many projects in their domain layer only have classes that have the same properties and are a direct reflection of the database, the so-called “Anemic entities”, we should design rich entities that have properties and behaviors, then we provide ourselves one place of business logic that is clear and easy to change.
High Hermetization – As the rest of the system will depend on the domain layer. We must be especially careful about what methods or properties we make available to the public, when we make too much public, other programmers will be able to use our logic in other layers, which causes leaks and duplication of business rules
Persistence ignorance – the domain layer should know about its state of persistence, thanks to which we can postpone the readiness for data or relational status for a later date, another advantage of this service will be in unit testing.
The way to achieve the above points will be presented in next posts.
Let’s move on to a real example!
An example project that i create is the “Estimation Tool” – a tool for managing the process of pricing services in IT companies.
Let’s take a look at the domain layer structure for the valuations module.

After the file names themselves, we can see what the domain consists of.
Let’s see what we have. Valuation that has some proposals, we also see a client who takes part in the valuation, and the employee ID appears, which will most likely be the author of the valuation. We can see what events for the proposal. Proposals can be rejected or approved.
What we can’t see DbContext, Handlers, Managers, Mappers, EntityConfiguration and etc. We can see pure business and this is wonderful for me.