Startup 和 Middleware(中间件)

在上一节(文章链接)中提到ASP.NET Core WebApp 必须含有Startup类,在本节中将重点讲解Startup类以及Middleware(中间件)在Startup类中的使用。

Startup Class

Startup Class中含有两个重要方法:Configure方法用于每次http请求的处理,比如后面要讲的中间件(Middleware),就是在configure方法中配置。而ConfigureServices方法在Configure方法前调用,它是一个可选的方法,可在configureServices依赖注入接口或一些全局的框架,比如EntityFramework、MVC等。Startup 类的 执行顺序:构造 -> configureServices->configure

1、Startup Constructor(构造函数)

主要实现一些配置的工作,方法参数如下:

  • IHostingEnvironment: 用于访问应用程序的特殊属性,比如applicationName,applicationVersion。通过IHostingEnvironment对象下的属性可以在构造中实现配置工作。比如获取当前根路径找到配置json文件地址,然后ConfigurationBuilder初始化配置文件,最后可以通过GetSection()方法获取配置文件。代码清单如下:

  1. var builder = new ConfigurationBuilder()
  2. .SetBasePath(env.ContentRootPath)
  3. .AddJsonFile("appsettings.json");
  4. var configuration = builder.Build();
  5. var connStr = configuration.GetSection("Data:DefaultConnection:ConnectionString").Value;

根目录下的配置文件如下:


  1. {
  2. "Data": {
  3. "DefaultConnection": {
  4. "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;"
  5. }
  6. }
  7. }
  • ILoggerFactory: 提供创建日志的接口,可以选用已经实现接口的类或自行实现此接口,下面代码使用最简单的控制台作为日志输出。
  1. public Startup(IHostingEnvironment env, ILoggerFactory logger)
  2. {
  3. var log = logger.CreateLogger("default");
  4. logger.AddConsole();
  5. log.LogInformation("start configure");
  6. }

2、ConfigureServices

主要实现了依赖注入(DI)的配置,方法参数如下:

  • IServiceCollection:整个ASP.NET Core 默认带有依赖注入(DI),IServiceCollection是依赖注入的容器,首先创建一个类(Foo)和接口(IFoo),代码清单如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. namespace WebApplication1
  6. {
  7. public interface IFoo
  8. {
  9. string GetFoo();
  10. }
  11. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. namespace WebApplication1
  6. {
  7. public class Foo : IFoo
  8. {
  9. public string GetFoo()
  10. {
  11. return "foo";
  12. }
  13. }
  14. }

在ConfigureServices 中将接口和实现注入至容器

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddTransient<IFoo, Foo>();
  4. }

如果想在每次Http请求后都使用IFoo的GetFoo()方法来处理,上面讲到可以在Configure方法中注册函数,在注册过程中由于使用了依赖注入(DI),因此可以直接通过RequestServices.GetRequiredService<IFoo>()泛型方法将IFoo对象在容器中取出。


  1. app.Run((context) =>
  2. {
  3. var str = context.RequestServices.GetRequiredService<IFoo>().GetFoo();
  4. return context.Response.WriteAsync(str);
  5. });

除了自己的接口外,还支持通过扩展方法添加更多的注入方法,比如EntityFramework、mvc框架都实现自己的添加方法。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Add framework services.
  4. services.AddDbContext<ApplicationDbContext>(options =>
  5. options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  6. services.AddIdentity<ApplicationUser, IdentityRole>()
  7. .AddEntityFrameworkStores<ApplicationDbContext>()
  8. .AddDefaultTokenProviders();
  9. services.AddMvc();
  10. // Add application services.
  11. services.AddTransient<IFoo, Foo>();
  12. }

3、Configure方法

主要是http处理管道配置和一些系统配置,参数如下:

  • IApplicationBuilder: 用于构建应用请求管道。通过IApplicationBuilder下的run方法传入管道处理方法。这是最常用方法,对于一个真实环境的应用基本上都需要比如权限验证、跨域、异常处理等。下面代码调用IApplicationBuilder.Run方法注册处理函数。拦截每个http请求,输出Hello World。
  1. public void Configure(IApplicationBuilder app)
  2. {
  3. app.Run((context) => context.Response.WriteAsync("Hello World!"));
  4. }
  • IHostingEnvironment: 同构造参数

  • ILoggerFactory: 同构造参数

Middleware

中间件是一个处理http请求和响应的组件,多个中间件构成了处理管道(Handler pipeline),每个中间件可以决定是否传递至管道中的下一中间件。一旦注册中间件后,每次请求和响应均会被调用。

1、中间件注册

中间件的注册在startup中的Configure方法完成,在configure方法中使用IApplicationBuilder对象的Run、Map、Use方法传入匿名委托(delegate)。上文示例注册IFoo.GetFoo()方法就是一个典型的中间件。

  • Run & Use: 添加一个中间件至请求管道。它们在功能很类似但是也存在一些区别,先来看下两个方法的定义。
  1. public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware);
  2. public static void Run(this IApplicationBuilder app, RequestDelegate handler);

Run是通过扩展方法语法来定义,传入入参是RequestDelegate的委托,执行完一个第一个run后是不会激活管道中的第二个run方法,这样代码执行结果只会输出一个“hello world!”


  1. app.Run((context) => context.Response.WriteAsync("Hello World!"));
  2. app.Run((context) => context.Response.WriteAsync("Hello World 1!"));

而use方法的入参则是Func<>的委托包含两个入参和一个返回值,这样在第一个函数执行完成后可以选择是否继续执行后续管道中的中间件还是中断。


  1. app.Use((context, next) =>
  2. {
  3. context.Response.WriteAsync("ok");
  4. return next();
  5. });
  6. app.Use((context, next) =>
  7. {
  8. return context.Response.WriteAsync("ok");
  9. });

  • Map: 含有两个参数pathMatche和configuration,通过请求的url地址匹配相应的configuration。例如可以将url路径是/admin的处理函数指定为如下代码:
  1. app.Map("/admin", builder =>
  2. {
  3. builder.Use((context, next) => context.Response.WriteAsync("admin"));
  4. });

2、常用中间件

Middleware 功能描述
Authentication 提供权限支持
CORS 跨域的配置
Routing 配置http请求路由
Session 管理用户会话
Static Files 提供对静态文件的浏览

这里有一些官方的示例,链接


以上内容有任何错误或不准确的地方请大家指正,不喜勿喷!

作者:帅虫哥 出处: http://www.cnblogs.com/vipyoumay/p/5640645.html

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

参考链接

[1] https://docs.asp.net/en/latest/fundamentals/middleware.html

[2] http://www.talkingdotnet.com/app-use-vs-app-run-asp-net-core-middleware/

 
分类: Net Core

Startup 和 Middleware(中间件)的更多相关文章

  1. ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)

    ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...

  2. ASP.NET MVC随想录——创建自定义的Middleware中间件

    经过前2篇文章的介绍,相信大家已经对OWIN和Katana有了基本的了解,那么这篇文章我将继续OWIN和Katana之旅——创建自定义的Middleware中间件. 何为Middleware中间件 M ...

  3. 创建自定义的Middleware中间件

    创建自定义的Middleware中间件 阅读目录 何为Middleware中间件 使用Inline方式注册Middleware 使用Inline+ AppFunc方式注册Middleware 定义原生 ...

  4. Django中Middleware中间件

    Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法.实际上当 ...

  5. .Net Core:Middleware中间件管道

    .NetCore中的Middleware是装配到管道处理请求和响应的组件:每个组件都可以决定是否继续进入下一个管道.并且可以在进入下一个管道前后执行逻辑: 最后一个管道或者中断管道的中间件叫终端中间件 ...

  6. Django分析之Middleware中间件

    写了几周的脚本,今天终于开始接触web框架了~学习Python的web框架,那么Django就几乎是必修课了,这次的工作是先打打下手,主要的任务是在setting中添加版本号,在渲染静态css,js的 ...

  7. Express ( MiddleWare/中间件 路由 在 Express 中使用模板引擎 常用API

    A fast, un-opinionated, minimalist web framework for Node.js applications. In general, prefer simply ...

  8. Django中的MiddleWare中间件

    1. middleware简介 Django的middleware的概念相当于SSH框架里面的filter的概念.中间键的作用就是对所有的request,在request前,和在response后做一 ...

  9. Jerry的CRM Middleware(中间件)文章合集

    我在SAP成都研究院做过的CRM中间件的项目其实并不是很多: 1. 2013年下半年和2014年上半年曾经支持过中联重科和蒙牛的CRM项目相关的中间件问题; 2. 2014年上半年做过一个CRM物料主 ...

随机推荐

  1. Codeforces Round #242 (Div. 2) &lt;A-D&gt;

    CF424 A. Squats 题目意思: 有n(n为偶数)个x和X,求最少的变换次数,使得X的个数为n/2,输出变换后的序列. 解题思路: 统计X的个数ans,和n/2比較,少了的话,须要把n/2- ...

  2. Objective-C中math.h数学计算公式介绍

    1. 三角函数  double sin (double); 正弦  double cos (double);余弦  double tan (double);正切 2 .反三角函数   double a ...

  3. sublime test3 使用技巧

    sublimeText3使用技巧 常用快捷键 ctrl+d :选中光标处的文本单元,继续按ctrl+d选中相同文本单元 alt+F3 :功能和ctrl+d类似,用于批量修改相同文本 shift+↑ ↓ ...

  4. Servlet之ServletContext以及文件操作

    ServletContext ------------------------------------ ServletContext是什么? 与cookie,session比较. 可以把它想象成一个共 ...

  5. Java 日期字符串与日期类型转换

    1.SimpleDateFormat.format 把日期类型转化到指定格式字符串 public static String convToString(Calendar cld,String temp ...

  6. (转)C++中extern “C”含义深层探索

    (转)C++中extern “C”含义深层探索 转自: http://www.cppblog.com/Macaulish/archive/2008/06/17/53689.html 1.引言 C++语 ...

  7. 0527 python 基础01

    折行的处理 \>>> print "hi \... hello Lucy!"hi hello Lucy! 自然字符串,字符串加上r或R前缀指定>>&g ...

  8. SQL中采用Newtonsoft.Json处理json字符串

    原文 SQL中采用Newtonsoft.Json处理json字符串 使用环境: SQL Server2005; VS2010; 关于SQL中部署CLR程序集的方法,网上一搜一大把,需要了解的自行查阅, ...

  9. Android studio如何使用SVN进行版本控制?

    通过这两天对Android Studio的研究,终于搞通了Android Studio的基本操作及与SVN的相关关联操作(这样才能在公司的开发工作中使用):Google年底将会停止ADT插件的更新和支 ...

  10. elk 分布式数据同步

    zjtest7-redis:/elk/elasticsearch/data/es_cluster/nodes/0/indices/library# strings ./1/index/_3.cfs | ...