问题

如何在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. 学号:201521123116 《java程序设计》第六周学习总结

    1. 本章学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2.书面作业 1.1.Object对象中的clone方法是 ...

  2. 戴建钊 201521123023《Java程序设计》第2周学习总结

    1. 本周学习总结 (1)String类:字符串连接"+",以前觉得方便但不知其原理,所以在有大量修改字符串操作的时候用得不亦乐乎,既浪费内存,又减缓效率.现在知道用Stringb ...

  3. 201521123111 《Java程序设计》第1周学习总结

    Java 第一周学习 1.刚开始学习对java还是陌生的,完全不清楚.通过刚开始的上课,有一点点的了解.刚开始可能相对比较基础,进程有点快,而且多媒体屏幕有点反光,所以还是蛮多不懂的.接下来应该好好努 ...

  4. 201521123064 《Java程序设计》第10周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. ① 定义Thread类的子类,覆盖Thread类的run()方法,然后创建该子类的实例(一般不用该方法,开销 ...

  5. 201521123116 《java程序设计》第十三周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jm ...

  6. Hibernate @Embeddable注释

    在hibernate中实现自定义类型,只要实现UserType接口即可或者以Component的形式提供.JPA的@Embedded注释可以在你的Entity中使用一般的Java对象,此对象需要用@E ...

  7. 实验:体会Oracle权限/角色赋予的差异

    环境:Oracle 11.2.0.4 目的:验证业务用户的权限/角色赋予的差异 现在创建两个用户jingyu2和jingyu3: SYS@jyzhao1> create user jingyu2 ...

  8. mysql 1093错误

    1093错误:修改一个表的时候子查询不能是同一个表 解决办法:把子查询再套一层,变成原来表的孙子查询就可以了 例如: INSERT INTO gg SET id3=(SELECT c.a+1 FROM ...

  9. 翻译一篇关于jedis的文章

    翻译 自 http://www.baeldung.com/jedis-java-redis-client-libraryIntro to Jedis – the Java Redis Client L ...

  10. JSP入门 Listener

    实现HttpSessionListener 编写一个OnlineUserListener类 package anni; import java.util.List; import javax.serv ...