如何传递参数给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 ...
随机推荐
- Python中元组相关知识
下面给大家介绍以下元组的相关知识: ·元组可以看成是一个不可更改的list 1.元组的创建 # 创建空元祖 t = () print(type(t)) # 创建只有一个值的元组 # 观察可知元组中如果 ...
- 微信小程序Map组件踩坑日记
刚刚又发生一个bug,搞得我头皮发麻,本来该美滋滋的回家准备度过愉快的周末,瞬间变成了日常修bug,来,开始填坑之路 情景再现: 首先说一说我们项目的需求, 点击下方,弹出抽屉 点击对应的地图打开相应 ...
- switch和if语句
if :基本语法: 1.单分支语句 : if(条件){代码块}else{代码块} 2.多分支语句 :if(条件){代码块} else if(条件){代码块}else{代码块} * 不要忘记添加else ...
- 安卓开发_WebView设置打开网页缩放问题
之前实现打开网页的方式,测试后,发现不能够对网页进行缩放操作,这对部分网页来说是十分不便的, 百度了一下解决方案 其实只需要加几行代码就可以实现网页缩放操作 settings.setUseWideVi ...
- PopupWindow 弹出时背景变暗
下面的PopupWindow 的高是相对于屏幕高设计,宽是获取的某一个控件的宽设置,位置位于某控件的上方,红色部分是设置弹出时屏幕变暗的. //设置contentView View contentV ...
- Django 信息
Request information USER admin GET No GET data POST No POST data FILES No FILES data COOKIES Variabl ...
- Python:GUI之tkinter学习笔记1控件的介绍及使用
相关内容: tkinter的使用 1.模块的导入 2.使用 3.控件介绍 Tk Button Label Frame Toplevel Menu Menubutton Canvas Entry Mes ...
- late_initcall和module_init的区别
在init.h中有如下定义: 详情参照:linux 设备驱动加载的先后顺序 #define pure_initcall(fn) __define_initcall("0",fn,1 ...
- Linux下内存查看命令
在Linux下面,我们常用top命令来查看系统进程,top也能显示系统内存.我们常用的Linux下查看内容的专用工具是free命令. Linux下内存查看命令free详解: 在Linux下查看内存我们 ...
- 阵列卡raid H730写策略write-through和write-back配置说明
问题描述: 最近公司新进了测试服务器,但是在做阵列的时候忘记写策略里面的配置意思了 就网上查了一下,然后顺便做个笔记记录一下 write-through 数据在写入存储的同时,要写入缓存,这种方式安全 ...