Custom Middleware in .Net core
Tags: csharp, dotnet, todayilearned
Published: 2021-09-27 19:11:13

There are basically two ways to implement custom middleware outside of startup class. In real world it’s not recommended to write middleware inside startup class.  In this article I will show those two ways to implement custom middleware.


#Custom middleware in a separate class#

So create a new class named MyCustomMiddleware and in the constructor initialize the RequestDelegate. Inside the class create a method named InvokeAsync which will call the next middleware and do some changes in the application. Here is the code.


```
    public class MyCustomMiddleware
    {
        private readonly RequestDelegate next;

        public MyCustomMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task InvokeAsync(HttpContext context) {
            await context.Response.WriteAsync("In custom middleware\n");
            await next.Invoke(context);
        }
    }
```

Now we need to register this class as a custom middleware. For that we need to extend the implementation of IApplicationBuilder interface. In the method body we have to register our middleware into the application pipeline by using UseMiddleware method.

```
    public static class MiddlwareExtensions
    {
        public static IApplicationBuilder UseCustomMiddleware(this IApplicationBuilder app)
            => app.UseMiddleware<MyCustomMiddleware>();
    }  
```

At the end we have to modify our Configure method in the startup class by this.

```
app.Use(async (contect, next) =>
            {
                await contect.Response.WriteAsync("Use middleware 1 start\n");
                await next.Invoke();
                await contect.Response.WriteAsync("Use middleware 1 end\n");
            });
            app.UseCustomMiddleware();

app.Run(async context =>
            {
                await context.Response.WriteAsync("Run middleware\n");
            });
```

When we run the application we can see our middleware get executed. And the results looks like this.

![custom class](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9e3tu6ukx2d2als5x1z3.PNG)


#Using IMiddleware interface#


Imiddleware interface have the invoke method by which we can get access both HttpContext and RequestDelegate. So we don’t need to create constructor for initializing delegates.
There are some benefits using this approach like 
1.	Application activates our custom middleware as per request as we register our middleware in the service as Transient.
2.	We can use strongly type with our middleware 



```
public class FactoryBasedCustomMiddleware : IMiddleware
    {
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            await context.Response.WriteAsync("Factory based custom middleware.\n");
            await next.Invoke(context);
        }
    }
```
Now as before we have to register our custom middleware class to the IApplicationBuilder.


```
public static class MiddlwareExtensions
    {
        public static IApplicationBuilder UseCustomMiddleware(this IApplicationBuilder app)
            => app.UseMiddleware<MyCustomMiddleware>();

        public static IApplicationBuilder UseFactoryBasedCustomMiddleware(this IApplicationBuilder app)
            => app.UseMiddleware<FactoryBasedCustomMiddleware>();
    }
```
Also change the Configure method like before.

```
app.Use(async (contect, next) =>
            {
                await contect.Response.WriteAsync("Use middleware 1 start\n");
                await next.Invoke();
                await contect.Response.WriteAsync("Use middleware 1 end\n");
            });
            app.UseCustomMiddleware();
            app.UseFactoryBasedCustomMiddleware();
app.Run(async context =>
            {
                await context.Response.WriteAsync("Run middleware\n");
            });

```
But in this approach we need to register our middleware class as a service in the ConfigureServices method.

```
services.AddTransient<FactoryBasedCustomMiddleware>();
```


Now the output will looks like this and we can see that both our custom middleware will execute.

![postman 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ad8aq2h15f67apro64g.PNG)
 

Both of this approach is easy to implement.

Feel free to comment and let me know your opinion about those approach.