When building applications with clean architecture, it’s essential to register the services that your application depends on in a clean and centralized manner. This is typically done in the application core layer. In this article, we will look at how to create a centralized service registration for core services such as AutoMapper, MediatR, and any other service needed, like Fluent Validation.
The Purpose of Application Core Service Registration
The application core layer is where we handle most of the business logic, and it is crucial that services such as mapping, request handling, and validation are made available to the rest of the application in a systematic way.
A centralized service registration ensures that:
- All necessary services are registered in one place.
- The application layer is decoupled from the infrastructure or external concerns.
- It’s easier to add or remove services as the application evolves.
Step 1: Creating the ApplicationServiceRegistration
Class
The first step in setting up service registration is to create a static class that will contain the method to register services.
Here’s a simple example of the ApplicationServiceRegistration
class:
namespace GloboTicket.TicketManagement.Application
{
public static class ApplicationServiceRegistration
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()));
return services;
}
}
}
In this class, we define a method AddApplicationServices
that extends the IServiceCollection
interface and registers the core services required by the application. Let’s break this down:
-
AutoMapper: This is a library that helps map objects from one type to another. By using
AddAutoMapper
, we automatically register all mapping profiles in the application domain.
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
-
MediatR: This library helps implement the Mediator pattern for handling requests (commands and queries) without tight coupling between components. The call to
AddMediatR
registers the handlers for the requests.
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()));
Step 2: Extending the Core with Fluent Validation
If you’re using Fluent Validation for your validation needs, you can extend the service registration to include validation by adding the following:
services.AddValidatorsFromAssemblyContaining<CreateEventCommandValidator>();
This registers all validators in the assembly, making them available throughout the application.
Updated ApplicationServiceRegistration
:
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()));
services.AddValidatorsFromAssemblyContaining<CreateEventCommandValidator>();
return services;
}
In this example, we’ve registered validators by referencing one of the validators (CreateEventCommandValidator
). Fluent Validation will automatically pick up all validators in the same assembly.
Step 3: Using the Service Registration
Once the ApplicationServiceRegistration
class is set up, you need to call the AddApplicationServices
method from the Startup.cs or Program.cs (depending on your .NET version) to register all these services at the application level.
For example, in ASP.NET Core, this might look like:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationServices(); // Registers all services from the application core layer
}
}
This call ensures that all necessary services, like AutoMapper, MediatR, and Fluent Validation, are registered and available throughout the application.
Conclusion
By centralizing service registration in the application core layer, we adhere to the principles of clean architecture and ensure that the core logic of the application remains isolated from external concerns. This approach makes it easier to maintain and extend the application as the number of services grows.
Using the ApplicationServiceRegistration
class, you can register essential services like AutoMapper, MediatR, and Fluent Validation in one place, making your code cleaner and more maintainable.
Source link
lol