如何传递参数给ASP.NET Core的中间件(Middleware)
问题描述
当我们在ASP.NET Core中定义和使用中间件(Middleware)的时候,有什么好的办法可以给中间件传参数吗?
解决方案
在ASP.NET Core项目中添加一个POCO类来传递参数到中间件,例如下面的GreetingOptions类
public class GreetingOptions
{
public string GreetAt { get; set; }
public string GreetTo { get; set; }
}
然后添加一个中间件GreetingMiddleware
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);
}
}
解决方案A:实例类型(Instance Type)
通过添加一个扩展方法类GreetingMiddlewareExtension,来配置中间件GreetingMiddleware,并传递参数GreetingOptions options
public static class GreetingMiddlewareExtension
{
public static IApplicationBuilder UseGreeting(this IApplicationBuilder app, GreetingOptions options)
{
return app.UseMiddleware<GreetingMiddleware>(options);
}
}
在ASP.NET Core项目中Startup类的Configure方法中,启用GreetingMiddleware中间件,并传递参数到中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseGreeting(new GreetingOptions
{
GreetAt = "Morning",
GreetTo = "Tahir"
});
}
解决方案B:方法类型(Function Type)
通过添加一个扩展方法类GreetingMiddlewareExtension,来配置中间件GreetingMiddleware,并通过委托Action<GreetingOptions> configureOptions来传递参数GreetingOptions
public static class GreetingMiddlewareExtension
{
public static IApplicationBuilder UseGreeting(this IApplicationBuilder app, Action<GreetingOptions> configureOptions)
{
var options = new GreetingOptions();
configureOptions(options); return app.UseMiddleware<GreetingMiddleware>(options);
}
}
在ASP.NET Core项目中Startup类的Configure方法中,启用GreetingMiddleware中间件,并通过委托Action<GreetingOptions>传递参数到中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseGreeting(options =>
{
options.GreetAt = "Morning";
options.GreetTo = "Tahir";
});
}
讨论
在前面的一篇文章中我们讨论了,定义和使用中间件(Middleware)的最好方法是,将中间件定义在一个单独的类中,然后通过扩展方法将其添加到ASP.NET Core的中间件管道(pipeline)中。
我们可以通过上面介绍的解决方案A和B,将需要传递到中间件的参数都封装为一个POCO类,并创建一个扩展方法,用下面两种方式作为扩展方法的参数:
注意:POCO实例是通过. UseMiddleware()方法的params object[]参数来传递到中间件的构造函数中的,也就是说我们可以通过params object[]来传递任意多个参数到中间件中,只要类型和中间件的构造函数参数匹配即可。我们还可以将依赖注入参数和POCO实例参数一起定义在中间件的构造函数中,如下所示:
public class GreetingMiddleware
{
private readonly RequestDelegate next;
private readonly GreetingOptions options; //IHostingEnvironment env是依赖注入参数,GreetingOptions options是POCO实例参数
public GreetingMiddleware(RequestDelegate next, IHostingEnvironment env, GreetingOptions options)
{
string environmentName = env.EnvironmentName; 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);
}
}
配置依赖注入服务
前面介绍的两种解决方案同样也可以用来配置依赖注入(dependency injection)服务的容器。
为了演示,我们先添加一个POCO类MessageOptions和用到的枚举MessageFormat
public enum MessageFormat
{
None,
Upper,
Lower
} public class MessageOptions
{
public MessageFormat Format { get; set; }
}
然后添加一个依赖注入接口IMessageService,及其实现类MessageService
public interface IMessageService
{
string FormatMessage(string message);
}
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();
}
}
同样,接下来我们就用两种解决方案,来定义MessageService的扩展方法类MessageServiceExtension
解决方案A:实例类型(Instance Type)
public static class MessageServiceExtension
{
// Instance Type
public static IServiceCollection AddMessageFormatter(this IServiceCollection services, MessageOptions options)
{
return services.AddScoped<IMessageService>(factory =>
{
return new MessageService(options);
});
}
}
在ASP.NET Core项目中Startup类的ConfigureServices方法中,注册IMessageService和MessageService的依赖注入服务
// Instance Type
public void ConfigureServices(IServiceCollection services)
{
services.AddMessageFormatter(new MessageOptions
{
Format = MessageFormat.Lower
});
}
解决方案B:方法类型(Function Type)
public static class MessageServiceExtension
{
// 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);
});
}
}
在ASP.NET Core项目中Startup类的ConfigureServices方法中,注册IMessageService和MessageService的依赖注入服务
// Function Type
public void ConfigureServices(IServiceCollection services)
{
services.AddMessageFormatter(options =>
{
options.Format = MessageFormat.Lower;
});
}
本文参考自:Passing Parameters to Middleware in ASP.NET Core 2.0
如何传递参数给ASP.NET Core的中间件(Middleware)的更多相关文章
- ASP.NET Core 开发-中间件(Middleware)
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- asp.net core mvc 中间件之WebpackDevMiddleware
asp.net core mvc 中间件之WebpackDevMiddleware WebpackDevMiddleware中间件主要用于开发SPA应用,启用Webpack,增强网页开发体验.好吧,你 ...
- ASP.NET Core:中间件
一.什么是中间件 我们都知道,任何的一个web框架都是把http请求封装成一个管道,每一次的请求都是经过管道的一系列操作,最终才会到达我们写的代码中.而中间件就是用于组成应用程序管道来处理请求和响应的 ...
- asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...
- 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?
原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- ASP.NET Core路由中间件[3]: 终结点(Endpoint)
到目前为止,ASP.NET Core提供了两种不同的路由解决方案.传统的路由系统以IRouter对象为核心,我们姑且将其称为IRouter路由.本章介绍的是最早发布于ASP.NET Core 2.2中 ...
- ASP.NET Core路由中间件[2]: 路由模式
一个Web应用本质上体现为一组终结点的集合.终结点则体现为一个暴露在网络中可供外界采用HTTP协议调用的服务,路由的作用就是建立一个请求URL模式与对应终结点之间的映射关系.借助这个映射关系,客户端可 ...
- ASP.NET Core之中间件
本文翻译自:http://www.tutorialsteacher.com/core/aspnet-core-middleware 基本概念 ASP.NET Core引入了中间件的概念,中间件是在AS ...
随机推荐
- 【代码笔记】Web-ionic-表单和输入框
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- loadrunner 运行场景-运行时设置
运行场景-运行时设置 by:授客 QQ:1033553122 A. 查看.修改单个脚本的运行时设置 a) 途径1: Scenario Groups.Scenario Groups Script ...
- Django基础篇--模板和路由分发
Django模板 首先什么是一个模板? 简单来说就是一个网页,可以被view响应给用户 目的是为了解决复杂的显示问题 2. 模板的设置问题 setting.py中的TEMPLATES配置 1)BACK ...
- python进程间通信--信号Signal
信号signal 是python进程间通信多种机制中的其中一种机制.可以对操作系统进程的控制,当进程中发生某种原因而中断时,可以异步处理这个异常. 信号通过注册的方式‘挂’在一个进程中,并且不会阻塞该 ...
- pycharm运行Django发生AppRegistryNotReady: Apps aren't loaded yet.
pycharm中运行django默认情况下并不是执行项目的,所以如果在非manage.py,会发生异常. raise AppRegistryNotReady("Apps aren't loa ...
- 【第四篇】SAP ABAP7.5x新语法之CREATE DATA&INTERFACE
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文地址:SAP ABAP7.5x系列之CREATE DA ...
- MVC| 路由测试代码
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System.Web; using ...
- php二维数组去重
php二维数组去重 前言:php一维数组去重很简单,直接array_unique($arr)即可,但是二维数组去重就得自己去写了 二维数组去重方法: /* * 二维数组去重 * 注意:二维数组中的元素 ...
- 修改css的(屏蔽)overflow: hidden;实现浏览器能把网页全图保存成图片
摘要: 1.项目需要,需要对网页内容“下载”保存成全图片 2.QQ浏览器等主流浏览器都支持这种下载保存功能 3.项目需要场景:编写好的项目维护文档,放在服务器上.如果是txt不能带图片可视化,如果wo ...
- flask框架的教程--虚拟环境的安装[一]
为什么需要安装虚拟环境呢? 因为虚拟环境中扩展包对本机软件中不影响 安装 查看是否安装了虚拟环境 安装虚拟环境的第三方工具 sudo pip install virtualenv sudo pip i ...