Click here to Skip to main content
15,880,427 members
Articles / Web Development / ASP.NET / ASP.NET Core

Passing Parameters to Middleware in ASP.NET Core 2.0

Rate me:
Please Sign up or sign in to vote.
2.09/5 (3 votes)
29 Aug 2017CPOL1 min read 16K   2   2
How do you pass parameters to middleware during its setup in ASP.NET Core. Continue reading...

Problem

How do you pass parameters to middleware during its setup in ASP.NET Core.

Solution

In an empty project, add a POCO class to hold parameters for the middleware:

C#
public class GreetingOptions
    {
        public string GreetAt { get; set; }
        public string GreetTo { get; set; }
    }

Add a middleware:

C#
public class GreetingMiddleware
    {
        private readonly RequestDelegate next;
        private readonly GreetingOptions options;

        public GreetingMiddleware(
            RequestDelegate next,
            GreetingOptions options)
        {
            this.next = next;
            this.options = options;
        }

        public async Task Invoke(
            HttpContext context)
        {
            var message = $"Good {this.options.GreetAt} {this.options.GreetTo}";
            await context.Response.WriteAsync(message);
        }
    }

Solution A: Instance Type

Add extension method to configure the middleware:

C#
public static IApplicationBuilder UseGreeting(
            this IApplicationBuilder app, GreetingOptions options)
        {
            return app.UseMiddleware<GreetingMiddleware>(options);
        }

Configure the middleware:

C#
public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            app.UseGreeting(new GreetingOptions
            {
                GreetAt = "Morning",
                GreetTo = "Tahir"
            });
        }

Solution B: Function Type

Add extension method to configure the middleware:

C#
public static IApplicationBuilder UseGreeting(
            this IApplicationBuilder app, Action<GreetingOptions> configureOptions)
        {
            var options = new GreetingOptions();
            configureOptions(options);

            return app.UseMiddleware<GreetingMiddleware>(options);
        }

Configure the middleware:

C#
public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            app.UseGreeting(options =>
            {
                options.GreetAt = "Morning";
                options.GreetTo = "Tahir";
            });
        }

Discussion

I discussed in an earlier post that it is good practice to define middleware in a separate class and add to the pipeline using extension methods. We may also need to pass information to our middleware classes though and I’ve come across two patterns for this when digging into ASP.NET Core source code and other samples online.

These are really straight forward as demonstrated in solution A and B above. We wrap our parameters in a POCO class and create an extension method that takes in either:

  1. POCO instance
  2. Function to call, which in turn sets up the POCO.

Note: The POCO is passed on to the middleware in its constructor. UseMiddleware() method takes in params object[] for arguments to be passed onto middleware constructor.

Configuring Services

These patterns could also be used for setting up dependency injection in the service container. To demonstrate, add a service:

C#
public class MessageService : IMessageService
    {
        private readonly MessageOptions options;

        public MessageService(MessageOptions options)
        {
            this.options = options;
        }

        public string FormatMessage(string message)
        {
            // use options
            return this.options.Format == MessageFormat.None ? message :
                    this.options.Format == MessageFormat.Upper ? message.ToUpper() :
                     message.ToLower();
        }
    }

Add either of these extension methods to configure services:

C#
// Instance Type
        public static IServiceCollection AddMessageFormatter(
            this IServiceCollection services, MessageOptions options)
        {
            return services.AddScoped<IMessageService>(factory =>
            {
                return new MessageService(options);
            });
        }

        // Function Type
        public static IServiceCollection AddMessageFormatter(
            this IServiceCollection services, Action<MessageOptions> configureOptions)
        {
            var options = new MessageOptions();
            configureOptions(options);

            return services.AddScoped<IMessageService>(factory =>
            {
                return new MessageService(options);
            });
        }

Configure services with either of these:

C#
// Instance Type
        public void ConfigureServices(
            IServiceCollection services)
        {
            services.AddMessageFormatter(new MessageOptions
            {
                Format = MessageFormat.Lower
            });
        }

        // Function Type
        public void ConfigureServices(
            IServiceCollection services)
        {
            services.AddMessageFormatter(options =>
            {
                options.Format = MessageFormat.Lower;
            });
        }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
GeneralMy vote of 5 Pin
E. Scott McFadden31-Aug-17 15:16
professionalE. Scott McFadden31-Aug-17 15:16 
GeneralRe: My vote of 5 Pin
User 104326431-Aug-17 22:01
User 104326431-Aug-17 22:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.