Organize Your ASP.NET Core DI Like a Pro! Move Service Registrations to a Separate Class for Clean, Scalable Code
Organizing your Dependency Injection (DI) setup in ASP.NET Core by moving service registrations to a separate class using extension methods is a simple yet powerful step toward writing cleaner, more maintainable, and scalable applications.
In modern ASP.NET Core (especially .NET 6 and later), the Program.cs file is the entry point of your web application. It:
Builds your web host
Sets up services (via DI)
Configures middleware
Starts the app
What Goes Wrong?
In small projects, you might only register a few services:
Program.cs looking like this:
builder.Services.AddScoped<IMyService, MyService>();
builder.Services.AddControllers();
But as the app grows:
Business logic gets more complex
The file becomes too long and messy.
It mixes service registration, routing, and app startup logic in one place.
It’s hard to read and harder to maintain.
If you want to update or replace a service, you have to dig through the clutter.
Now, Program.cs starts looking like this:
builder.Services.AddScoped<IMyService, MyService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IEmailSender, SendGridEmailSender>();
builder.Services.AddScoped<IPaymentProcessor, StripeProcessor>();
builder.Services.AddScoped<IReportGenerator, PdfReportGenerator>();
builder.Services.AddDbContext<AppDbContext>(...);
builder.Services.AddAutoMapper(typeof(Startup));
builder.Services.AddControllers();
Solution
Move the service registrations to a separate file using an extension method. Then in Program.cs, you just call:
builder.Services.DIScope();
Example
1. Define service IGreetingService
namespace DIServiceExtension.Service
{
public interface IGreetingSerice
{
string Greet(string message);
}
public class GreetingService : IGreetingSerice
{
public string Greet(string message="Hello Developers...")
{
return message;
}
}
}
2. Define serivce IEmailSerice
using DIServiceExtension.Helper;
namespace DIServiceExtension.Service
{
public interface IEmailService
{
string SendMail();
}
public class EmailService:IEmailService
{
private readonly HelperService _helperService;
public EmailService(HelperService helperService)
{
_helperService = helperService;
}
public string SendMail()
{
return $"Mail sent successfully! on {_helperService.GetUTCDateTime()}";
}
}
}
3. Define HelperService
namespace DIServiceExtension.Helper
{
public class HelperService
{
public DateTime GetUTCDateTime()
{
return DateTime.UtcNow;
}
}
}
4. Create an Extension Method
using DIServiceExtension.Helper;
using DIServiceExtension.Service;
using Microsoft.Extensions.DependencyInjection;
namespace DIServiceExtension
{
public static class ServiceExtension
{
/* public static void DIScope(this IServiceCollection services)
{
services.AddScoped<IEmailService, EmailService>();
services.AddScoped<IGreetingSerice, GreetingService>();
services.AddScoped<HelperService>();
}*/
public static IServiceCollection DIScope(this IServiceCollection services)
{
services.AddScoped<IEmailService, EmailService>();
services.AddScoped<IGreetingSerice, GreetingService>();
services.AddScoped<HelperService>();
return services;
}
}
}
5. Use the Extension Method in Program.cs
builder.Services.DIScope();
The Benefits
1. Cleaner Code
Program.cs is focused only on application startup
DI logic is encapsulated in its own file
2. Better Separation of Concerns
DI setup is not mixed with routing, middleware, or host configuration
You can reuse or test the DI configuration independently
3. Easier Maintenance
Adding a new service? Just update one centralized method.
Need to switch to a different implementation? Update it in one place.
4. Scalability
Large apps often register hundreds of services
You can break your DI setup into multiple layers:
builder.Services
.AddInfrastructureServices()
.AddApplicationServices()
.AddCustomServices();
Want to See It in Action?
If you'd like a visual walkthrough of everything covered in this post — with real code examples and a step-by-step explanation —
Check out my YouTube video here: Watch
Don’t forget to like, comment, and subscribe if you find it helpful!
Comments
Post a Comment