问题

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

答案

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

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);
}

使用中间件:

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

答案2:函数类型

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

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

使用中间件:

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

上述两种方法结果一致。

运行,此时页面显示:

讨论

之前我们曾讨论过,在单独的类中定义中间件并使用扩展方法将其添加到请求管道中是最佳实践。我们也可能需要向中间件传入参数,通过对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/

[译]ASP.NET Core 2.0 带初始参数的中间件的更多相关文章

  1. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  2. [译]ASP.NET Core 2.0 中间件

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...

  3. [译]ASP.NET Core 2.0 全局配置项

    问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...

  4. [译]ASP.NET Core 2.0 机密配置项

    问题 如何在ASP.NET Core 2.0中保存机密配置项(不用将其暴露给源代码管理器)? 答案 创建一个ASP.NET Core 2.0空项目,在项目节点上点击右键,并点击菜单项 - 管理用户机密 ...

  5. [译]ASP.NET Core 2.0 会话状态

    问题 如何在ASP.NET Core 2.0中存储会话状态? 答案 创建一个空项目,修改Startup类的ConfigureServices()方法,添加会话状态服务和它后台的存储服务: public ...

  6. [译]ASP.NET Core 2.0 本地文件操作

    问题 如何在ASP.NET Core 2.0中受限地访问本地目录和文件信息? 答案 新建一个空项目,修改Startup类,添加访问本地文件所需的服务: public void ConfigureSer ...

  7. [译]ASP.NET Core 2.0 网址重定向

    问题 如何在ASP.NET Core 2.0中实现网址重定向? 答案 新建一个空项目,在Startup.cs文件中,配置RewriteOptions参数并添加网址重定向中间件(UseRewriter) ...

  8. [译]ASP.NET Core 2.0 路由引擎

    问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...

  9. [译]ASP.NET Core 2.0 路由引擎之网址生成

    问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...

随机推荐

  1. 201521123045 《JAVA程序设计》第1周学习总结 1

    1. 本周学习总结 学习了入门的java知识,知道了jdk.eclipse等基础软件,了解了如何编译最基础的java程序.知道了java的基本原理以及java的几种数据类型.掌握使用简单编译器编写ja ...

  2. 陈敏-第一周Java课程总结

    一.本周学习总结 1.感受到JAVA的神奇魅力,以及其跨平台的优势 2.第一次接触感觉还是有很多不懂. 3.了解了JDK 二.书面作业 (一)为什么java程序可以跨平台运行?执行java程序的步骤是 ...

  3. 201521123079《java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 流与文件 I/O流:Input/Output处理的简称,本质上就是一个数据序列.分为输入流Input Stre ...

  4. PKI信息安全知识点详细解答包含HTTPS

    1. 什么是X.509? X.509标准是ITU-T设计的PKI标准,他是为了解决X.500目录中的身份鉴别和访问控制问题设计的. 2. 数字证书 数字证书的意义在于回答公钥属于谁的问题,以帮助用户安 ...

  5. day2_操作系统

    一.为什么要有操作系统       因为计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成.现代计算机系统复杂 每位计算机程序员不可能全部的掌 ...

  6. RAID磁盘阵列

    什么是RAID 独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks),简称磁盘阵列.其基本思想就是把多个相对便宜的硬盘组合起来,成为一个硬盘阵列组, ...

  7. 将数据转成JSON

    前言 前面我们在使用Strus2的时候,Struts2自带了组件能够让JavaBean对象.集合转成是JSON,不用我们自己拼接-这是非常方便的.但是,我们不一定使用Struts2框架来做开发呀.因此 ...

  8. day12<常见对象+>

    常见对象(Scanner的概述和方法介绍) 常见对象(Scanner获取数据出现的小问题及解决方案) 常见对象(String类的概述) 常见对象(String类的构造方法) 常见对象(String类的 ...

  9. 杂谈--DML触发器学习

    触发器按类型分为三类: 1. DML 触发器,在数据变更时触发: 2. DDL 触发器,在修改数据库级别或实例级别对象时触发: 3. Login 触发器,在用户登录时触发: 最常见的是DML触发器,D ...

  10. oracle pl/sql 包

    包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成.1).我们可以使用create package命令来创建包,如:i.创建一个包sp_packageii.声明该包有一个过程update_sal ...