[译]ASP.NET Core 2.0 带初始参数的中间件

问题

如何在ASP.NET Core 2.0向中间件传入初始参数?app

答案

在一个空项目中,建立一个POCO(Plain Old CLR Object)来保存中间件所需的参数:async

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

添加一个中间件:函数

public class GreetingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly GreetingOptions _options;

    public GreetingMiddleware(RequestDelegate next, GreetingOptions options)
    {
        _next = next;
        _options = options;
    }

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

答案1:实例类型

添加一个扩展方法来配置中间件:学习

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

使用中间件:ui

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

答案2:函数类型

添加一个扩展方法来配置中间件:this

public static IApplicationBuilder UseGreetingMiddlewareAction(this IApplicationBuilder app, Action<GreetingOptions> optionsAction)
{
    var options = new GreetingOptions();
    optionsAction(options);

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

使用中间件:spa

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

上述两种方法结果一致。code

运行,此时页面显示:orm

讨论

以前咱们曾讨论过,在单独的类中定义中间件并使用扩展方法将其添加到请求管道中是最佳实践。咱们也可能须要向中间件传入参数,经过对ASP.NET Core源代码以及其余在线示例的学习,我总结出来上面两种模式。中间件

上述的两种解决方法都很是直观。咱们将参数封装到一个POCO类中,而后建立一个扩展方法来接受下面的参数:

1. POCO实例

2. 须要调用的函数(在函数内设置POCO)

注:POCO实例经过构造函数传入中间件。UseMiddleware()方法接收可变参数params object[],并将这些参数传入中间件构造函数。

配置服务

这些模式也能用于向服务容器中添加服务实例。为了便于说明,咱们先添加一个服务:

public interface IMessageService
{
    string FormatMessage(string message);
}

public class MessageService : IMessageService
{
    private readonly GreetingOptions _options;

    public MessageService(GreetingOptions options)
    {
        _options = options;
    }

    public string FormatMessage(string message)
    {
        return $"Good {_options.GreetAt} {_options.GreetTo} - {message}";
    }
}

添加以下任一个扩展方法来配置服务:

public static IServiceCollection AddMessageService(this IServiceCollection services, GreetingOptions options)
{
    return services.AddScoped<IMessageService>(factory => new MessageService(options));
}

public static IServiceCollection AddMessageServiceAction(this IServiceCollection services, Action<GreetingOptions> optionsAction)
{
    var options = new GreetingOptions();
    optionsAction(options);

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

在Configure()中使用此服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMessageService(new GreetingOptions
    {
        GreetAt = "Morning",
        GreetTo = "Tahir"
    });

    services.AddMessageServiceAction(options =>
    {
        options.GreetAt = "Morning";
        options.GreetTo = "Tahir";
    });
}

由于ConfigureServices()先于Configure()执行,所以咱们能够直接在Configure()注入此服务:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMessageService msg)
{
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(msg.FormatMessage("by sanshi"));
    });
}

运行,此时页面显示:

 

 

源代码下载

 

原文:https://tahirnaushad.com/2017/08/29/passing-parameters-to-middleware-in-asp-net-core-2-0/

相关文章
相关标签/搜索