Introduction
Implementing the Mediator Design Pattern in an ASP.NET Core Web API with a 3-tier architecture involves creating separate layers for presentation, business logic, and data access. The Mediator Design Pattern helps in decoupling the components by using a mediator to handle communication between them. In this example, I will focus on building a simple library books CRUD (Create, Read, Update, Delete) application.
1. Create the Solution and Project Structure
Create a new ASP.NET Core Web API project with the following structure.
- LibraryBooks.API (Presentation Layer - Web API)
- LibraryBooks.Application (Business Logic Layer - Mediator Implementation)
- LibraryBooks.Domain (Domain Layer - Models and Interfaces)
- LibraryBooks.Infrastructure (Data Access Layer - Database operations)
2. Install Required Packages
In each project, install the necessary packages.
//Sardar Mudassar Ali Khan
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
3. Define Domain Models
In the LibraryBooks.Domain project, define the models.
// Sardar Mudassar Ali Khan
// LibraryBooks.Domain/Models/LibraryBook.cs
public class LibraryBook
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}
4. Define Mediator Requests and Handlers
In the LibraryBooks.Application project, define the requests and handlers.
// Sardar Mudassar Ali Khan
// LibraryBooks.Application/Requests/ReadBook.cs
public class ReadBookRequest : IRequest<LibraryBook>
{
public int BookId { get; set; }
// Add other properties as needed
}
// Sardar Mudassar Ali Khan
// LibraryBooks.Application/Handlers/ReadBookHandler.cs
public class ReadBookHandler: IRequestHandler<ReadBookRequest, LibraryBook>
{
private readonly IBookRepository _bookRepository;
public ReadBookHandler(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
public async Task<LibraryBook> Handle(ReadBookRequest request, CancellationToken cancellationToken)
{
var book = await _bookRepository.GetAsync(request.BookId);
return book;
}
}
//Sardar Mudassar Ali Khan
// LibraryBooks.Application/Requests/UpdateBook.cs
public class UpdateBookRequest: IRequest
{
public int BookId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
}
// Sardar Mudassar Ali Khan
// LibraryBooks.Application/Handlers/UpdateBookHandler.cs
public class UpdateBookHandler: IRequestHandler<UpdateBookRequest>
{
private readonly IBookRepository _bookRepository;
public UpdateBookHandler(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
public async Task<Unit> Handle(UpdateBookRequest request, CancellationToken cancellationToken)
{
var existingBook = await _bookRepository.GetAsync(request.BookId);
if (existingBook != null)
{
// Update book properties
existingBook.Title = request.Title;
existingBook.Author = request.Author;
// Update other properties as needed
await _bookRepository.UpdateAsync(request.BookId, existingBook);
}
return Unit. Value;
}
}
// LibraryBooks.Application/Requests/DeleteBook.cs
public class DeleteBookRequest: IRequest
{
public int BookId { get; set; }
}
// LibraryBooks.Application/Handlers/DeleteBookHandler.cs
public class DeleteBookHandler: IRequestHandler<DeleteBookRequest>
{
private readonly IBookRepository _bookRepository;
public DeleteBookHandler(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
public async Task<Unit> Handle(DeleteBookRequest request, CancellationToken cancellationToken)
{
await _bookRepository.DeleteAsync(request.BookId);
return Unit. Value;
}
}
Join the conversation! Your thoughts help the community grow.