Domain Driven Design (DDD) approach in .NET Applications
Table of Contents
In this article, we will learn about the Domain-Driven Design pattern and get a basic idea of how to organize the layers and what components each layer can have, for building robust enterprise applications.
What is Domain Driven Design (DDD)?
DDD is a software development architecture-style approach that tells you how to manage your domain complexity.
Eric Evans is the author of “Domain-Driven Design: Tackling Complexity in the Heart of Software” which introduced and elaborated on the principles & practices of Domain-Driven Design (DDD), published in 2003.
DDD is only intended for large projects, like more than 6 or 8 months, with large complexity. Domain refers to the subject area around which the application that is being developed is centered. For example, the topic/domain could be “online order processing” which you can use to develop an Online Shopping Application. It can have multiple domains like delivery, transport and others within the same application.
The goal of implementing DDD is to handle complex scenarios so that domain experts and developers can collaborate effectively with minimal misunderstanding and arguments.

Pros:
- Simple communication: Communication between developers & experts becomes much easier
- Object-oriented: DDD is Object-oriented which gives more flexibility, the entire system can be modified & improved regularly.
- Structured Complexity: By breaking down the domain into smaller, manageable parts (entities, value objects, aggregates, etc.), DDD helps in managing the inherent complexity of large systems.
- Bounded Contexts: DDD encourages defining clear boundaries for different parts of the system, known as bounded contexts, which isolate different domains and reduce dependencies.
- Clear Separation of Concerns: By organizing code around the business domain, DDD ensures that changes in business logic are localized, reducing the risk of unintended side effects.
- Test-Driven Development (TDD): DDD naturally complements TDD by encouraging the development of small, focused units of code that are easy to test.
Cons:
- Domain knowledge required: There has to be at least one domain specialist who understands the precise characteristics of the subject that’s at the center of the application
- Doesn’t work for highly technical projects: DDD is perfect for applications that have complex business logic, not which is highly technical.
Domain Driven Design – Folder Structure

Let’s look at the diagram above to understand how to create folder structures and see what files can go in each folder.
Note: These structures/ components can be different for each application depending on business needs, so you can change them as needed.
Domain:
📁 Abstractions
📁 Repositories
- IRepository
- IUnitOfWork.cs
📁 Errors
- DomainErrors.cs (static error classes)
📁 Enumerations
📁 Exceptions
- BadRequestException.cs
- NotFoundException.cs
📁 Models/Entities
- EmployeeEntity.cs
📁 Primitives
- JsonResult.cs
- AssemblyReference.cs
Application:
// ProjectReference = Domain.csproj
📁 Behaviours
- ValidationBehaviours.cs
📁 Exceptions
📁 Errors
- ValidationErrors.cs (static error classes)
📁 Features (Vertical Slice Architecture)
📁 Feature1[Employee] (CQRS Design Pattern using MediatR)
📁 Command
📁 Create
- CreateEmployeeCommand.cs
- CreateEmployeeCommandHandler.cs
📁 Queries
📁 GetAll
- GetAllEmployeeQuery.cs
- GetAllEmployeeQueryHandler.cs
- AssemblyReference.cs
Infrastructure:
// ProjectReference = Domain.csproj
📁 Authentication
- JwtProvider.cs
- JwtSettings.cs
📁 Configurations
📁 Emails
- MailSettings.cs
- EmailService.cs
📁 Logging
📁 Messaging
- MessageSettings.cs
📁 Notifications
- EmailNotificationService.cs
📁 Migrations
- ApplicationDbContextModelSnapshot.cs
📁 Repositories
- EmployeeRepository.cs
- GenericRepository.cs
- ApplicationDbContext.cs
- AssemblyReference.cs
Presentation:
// ProjectReference = Application.csproj
📁 Controllers
- EmployeeController.cs
- AssemblyReference.cs
Web:
// ProjectReference = Infrastructure.csproj
// ProjectReference = Presentation.csproj
📁 Middleware
📁 ExceptionHandling.cs
- The Domain Layer is the core of the application, containing the business logic and rules. It represents the fundamental business concepts and behaviors, value objects, rules, abstractions, base classes, etc.
- The Application Layer coordinates the application’s activities, serving as a mediator between the domain layer and the presentation/infrastructure layers. It doesn’t handle business rules but coordinates tasks using domain objects.
- The Infrastructure Layer provides technical capabilities to support the other layers. It handles concerns such as data persistence, messaging, logging, and external integrations.
- The Presentation Layer is responsible for the user interface and interaction. It handles the display of information and user input, interacting with the application layer to execute commands and retrieve data. For example controllers or User Interfaces (UI) or any front-end interface
To support Dependency Injection you need to define all of your service registration inside the Web application. The web applications will have access to the controllers that are defined in the Presentation layer and will have access to anything that is defined inside our application.
Note: Don’t put the Controller directly in the Web application. If you do, it can access the Infrastructure project, for example allowing direct database access using something like _dbcontext. This breaks the CQRS pattern for separating read/write operations, making it impossible to enforce the proper architecture. Instead, place the Controller in the Presentation Class library, where we can control all the libraries we are referencing.