C# Extension Methods

C# Extension Methods

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:

  1. What are extension methods?
  2. What problem does it solve?
  3. Sample application using extension method

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:

  1. Enhancing Existing Types: Extension methods allow you to add methods to existing classes or interfaces without modifying their source code or creating derived types. This is particularly useful when you want to add functionality to a class or interface from a library or a framework that you can't or don't want to modify.
  2. Improving Readability: Extension methods can make your code more readable and intuitive. They allow you to write methods that look like instance methods of a class or interface, which can be more intuitive to use than static methods.
  3. Providing Default Implementations (for Interfaces): While C# doesn't support default implementations in interfaces (unlike some other languages such as Java), you can use an extension method to provide a default implementation for an interface method. This can be useful when you want all or most implementations of an interface to use the same method implementation.
  4. Adding Functionality to Interfaces: If you want to add new methods to an interface without breaking existing implementations, you can use extension methods. This allows you to add functionality to an interface without affecting classes that already implement the interface.

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.

  • SocialNetworkingAPI as starter project containing controller code.
  • Domain project contains code for entity.
  • Persistence containing code for database migrations.

  1. This code is an end to end working web api. The application is SocialNetworkingAPI where User as an entity.
  2. The User table is created in the SQLite database using Entity core framework.
  3. Data is inserted using Seed class when application loads.
  4. Then the user entity can be retrieved though rest endpoint using GetUsers() and GetUser(id) action methods in controller.

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

回复

要查看或添加评论,请登录

Megha Sahay的更多文章

  • A gentle introduction to Java Script

    A gentle introduction to Java Script

    JavaScript is a versatile, high-level programming language that's widely used in web development. It can be used to add…

  • Stack vs Heap - Understanding memory in C#

    Stack vs Heap - Understanding memory in C#

    Managing memory in important for any programming language. This impacts both reliability and performance of a…

    1 条评论
  • Performance improvement for React based apps

    Performance improvement for React based apps

    Hello everyone welcome to this weeks post. In this week we will discuss few points that will improve the performance of…

  • Understanding Ransomware

    Understanding Ransomware

    In this issue of newsletter we will explore ransomware. I will provide an introduction to ransomware.

    1 条评论
  • Web API - An Introduction

    Web API - An Introduction

    In this issue of newsletter we will explore the APIs. I will provide an introduction to API.

  • Docker - A beginners guide

    Docker - A beginners guide

    Docker is an open-source platform that allows developers to build, package, and deploy applications as lightweight…

  • A Developer’s Dilemma: Selecting the Perfect Protocol - GraphQL, REST, gRPC or WebSockets?

    A Developer’s Dilemma: Selecting the Perfect Protocol - GraphQL, REST, gRPC or WebSockets?

    Selecting the ideal protocol for your unique Project Introduction Many software architects face problems to choose…

  • CQRS in C#

    CQRS in C#

    In this edition of newsletter we will understand what is CQRS pattern with a sample clean architecture example. By the…

  • Implementing ORM with .Net

    Implementing ORM with .Net

    We will look at implementing Object–relational mapping with Entity core framework. We will cover the following topics.

  • Using GraphQL with C#

    Using GraphQL with C#

    An application demonstrating use of Graphql with C#. In todays newsletter we will look into how can we use GraphQL with…

社区洞察

其他会员也浏览了