C# Extension Methods
Megha Sahay
Full Stack Development || DevOps || C#/.Net || Java/J2EE || Python || Masters in AI & ML || Ex HSBC || Epiroc Sweden
In this week's newsletter we will take a closer look at extension methods in C#. By the end of this article you should be able to:
What is C# extension methods?
It is method is a static method that can be used to add additional functionalities without changing the original definition.
It allows you to add functionalities that you may not be able to inherit may be because the class is sealed or you are using a third party library where you don't have the source code.
You can add extension methods to built in class/interface or custom class/interface.
What problem does it solve?
Extension methods in C# can solve several problems in both classes and interfaces:
Remember, while extension methods can be very useful, they should be used judiciously. Overuse of extension methods can lead to code that is difficult to understand and maintain.
Review of previous post
In this sample we will use the existing EFCoreDemo in our previous post.
A small review of what has been done in the sample application so far.
This is a sample application based on clean architecture. The code is divided into three projects namely.
领英推荐
The detailed explanation of code is available in my LinkedIn article here.
We will use extension methods on the Program.cs class of the EFCoreDemo.
Sample Application
We have the following existing Program.cs class in SocialNetworkingAPI folder as shown below:
using Application;
using Microsoft.EntityFrameworkCore;
using Persistence;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"));
});
builder.Services.AddMediatR
(
cfg => cfg.RegisterServicesFromAssemblies(typeof(ListUsers.Handler).Assembly
));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
// When we are done with this scope will be disposed and cleaned for memory
// good developer automatically disposes of the scope
using var scope = app.Services.CreateScope();
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<DataContext>();
await context.Database.MigrateAsync();
await Seed.SeedData(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occured during migration");
}
app.Run();
We will move the code for builder to another extension method.
Create a folder called extension as shown below:
Create a class called ApplicationExtensions.cs as shown above. Copy all the services.builder code from Program.cs file. Make the class static and add a static method called AddApplicationServices as shown below:
using Application;
using Microsoft.EntityFrameworkCore;
using Persistence;
namespace SocialNetworkingAPI.Extensions
{
public static class ApplicationExtensions
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services, WebApplicationBuilder builder)
{
services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"));
});
services.AddMediatR
(
cfg => cfg.RegisterServicesFromAssemblies(typeof(ListUsers.Handler).Assembly)
);
return services;
}
}
}
Now rename builder.services to services parameter that takes type IServiceCollection. So, here we have created an extension method that takes the parameter of type this IServiceCollection. Which means when we call builder.services we will have AddApplicationServices() where we can pass the builder argument. This is an example of Extension Method Dependency Registration where we have moved builder.services dependencies into an extension method and then invoking that extension method within the Program file.
The full repository is available here.
Custom Extension Methods in C# enable extending existing classes or interfaces without modifying their original code, enhancing code readability, maintainability, and promoting code reusability. Embrace this powerful feature for cleaner, more scalable code. #CSharp #ProgrammingTips