在上一节(文章链接)中提到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()方法获取配置文件。代码清单如下:

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

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


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

2、ConfigureServices

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace WebApplication1
{
public interface IFoo
{
string GetFoo();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace WebApplication1
{
public class Foo : IFoo
{
public string GetFoo()
{
return "foo";
}
}
}

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

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

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


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

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

public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders(); services.AddMvc(); // Add application services.
services.AddTransient<IFoo, Foo>(); }

3、Configure方法

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

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

  • ILoggerFactory: 同构造参数

Middleware

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

1、中间件注册

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

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

 public static void Run(this IApplicationBuilder app, RequestDelegate handler);

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


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

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


app.Use((context, next) =>
{
context.Response.WriteAsync("ok");
return next();
});
app.Use((context, next) =>
{
return context.Response.WriteAsync("ok");
});

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

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/

ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)的更多相关文章

  1. ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行

    ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行 核心框架 ASP.NET Core APP 创建与运行 总结 之前两篇文章简析.NET Core 以及与 .NET Framew ...

  2. ASP.NET Core 运行原理剖析

    1. ASP.NET Core 运行原理剖析 1.1. 概述 1.2. 文件配置 1.2.1. Starup文件配置 Configure ConfigureServices 1.2.2. appset ...

  3. ASP.NET Core 运行原理剖析 (转载)

    1.1. 概述 在ASP.NET Core之前,ASP.NET Framework应用程序由IIS加载.Web应用程序的入口点由InetMgr.exe创建并调用托管.以初始化过程中触发HttpAppl ...

  4. ASP.NET Core 运行原理解剖[1]:Hosting

    ASP.NET Core 是新一代的 ASP.NET,第一次出现时代号为 ASP.NET vNext,后来命名为ASP.NET 5,随着它的完善与成熟,最终命名为 ASP.NET Core,表明它不是 ...

  5. ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍

    在上一章中,我们介绍了 ASP.NET Core 的启动过程,主要是对 WebHost 源码的探索.而本文则是对上文的一个补充,更加偏向于实战,详细的介绍一下我们在实际开发中需要对 Hosting 做 ...

  6. ASP.NET Core 运行原理解剖[3]:Middleware-请求管道的构成

    在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 HttpModule 来实现对请求管道事件监 ...

  7. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    HttpContext是ASP.NET中的核心对象,每一个请求都会创建一个对应的HttpContext对象,我们的应用程序便是通过HttpContext对象来获取请求信息,最终生成响应,写回到Http ...

  8. ASP.NET Core 运行原理解剖[5]:Authentication

    在现代应用程序中,认证已不再是简单的将用户凭证保存在浏览器中,而要适应多种场景,如App,WebAPI,第三方登录等等.在 ASP.NET 4.x 时代的Windows认证和Forms认证已无法满足现 ...

  9. Startup 和 Middleware(中间件)

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

随机推荐

  1. crossplatfrom---electron入门教程

    1.atom/electron github: https://github.com/atom/electron 中文文档: https://github.com/atom/electron/tree ...

  2. angularjs揭秘

    angularjs揭秘

  3. Screeps ———— A MMO Strategy Sandbox Game for Programmers

    At the beginning, let's see three of this game's captures. Yes, As what you see in these pictures, y ...

  4. 【WP 8.1开发】How to 图像处理

    在今天的吹牛节目开始之前,先交代一件事: 关于玩WP 8.1开发所使用的VS版本问题.对版本的要求是2013的Update2,这是最低要求,只要是这个版本或以上都可以,而update3,update4 ...

  5. Winform 生成不需要安装的exe可执行文件 ILMerge使用

    今天应领导要求,把一个程序打包生成一个可以执行的exe文件,不是安装包那种,类似于绿色文件,就是一个exe,可以直接运行.上网查了一下有一个工具可以实现ILMerge. 参照两个文档http://bl ...

  6. C指针(二)

    原文链接:http://www.orlion.ga/924/ 一.指针与const限定符 const限定符与指针结合起来常见的情况有一下几种: const int *a; int const *a; ...

  7. C#中的readonly与const的比较

    C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景.工作原理 readonly为运行时常量,程序运行时进行赋 ...

  8. js实现多张图片每隔一秒换一张图片

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlkAAAHWCAIAAADLlAuAAAAgAElEQVR4nOzd5XNc157w+/l7bt2n6t

  9. 数据可视化-EChart2.0.0使用中遇到的2个问题

    之前项目中都是使用FusionChart和HighChart,基本都是没有购买商业许可.然后现在开发的系统需要交付给客户使用.所以现在图表控件不能直接使用FusionChart和HighChart,通 ...

  10. IOS开发之显示微博表情

    在上一篇博客中山寨了一下新浪微博,在之后的博客中会对上一篇代码进行优化和重用,上一篇的微博请求的文字中有一些表情没做处理,比如带有表情的文字是这样的“我要[大笑],[得意]”.显示的就是请求的字符串, ...