ASP.NET Core&&MVC

1、ASP.NET Core MVC源码主要包含:

  MVC.CORE 源码的核心实现,包含认证,过滤,模型绑定,路由等等

  MVC.Razor  Razor视图的拓展引擎实现,模板引擎等

  MVC.TagHelper  Razor中TagHelper的主要实现

  MVC.ViewFeatures  Razor中视图组件的渲染

 2、.NET Core源码的使用:

  2.1 首先用VS创建一个.NET Core的MVC站点,查看当前框架版本和想跟踪代码源的目标包的版本。

  2.2 以2.1框架为例。

    2.2.1 因为执行源文件之后的包都是pre-view预发行版,所以必须使用高于当前框架一个版本才能安装进项目进行调试。所以都下载2.2的release版本。

    2.2.2 当前想调试MVC源码,则下载MVC rel2.2,然后powsershell升级到4.0版本,运行MVC源码中的build.cmd文件,生成对应的MVC包。

    2.2.3 创建一个空的.NET Core 的站点,加载nuget.server.core这个包,发布就行了(传统.NET版本则下载nuget.server包)

    2.2.4 将MVC build好的包放到自己创建的nugetserver的Packages文件夹里面,VS中配置我们的nugetserver就行了。

    2.2.5 取消默认的nugetserver官网的链接,删除以及下载的MVC包,然后下载我们自己的mvc包,启动站点就可以跟踪源码了。

3、路由主要是将HTTP请求映射到正确的handler(路由处理器)上。在MVC中就是路由到control的Action上。

4、路由从请求的URL中提取信息然后根据这些信息进行匹配,从而映射到具体的处理程序中。因此路由是基于URL构建的一个中间件框架。

5、当前,使用.NET Core源码的方式有两种:符号定位法和本地建立nugetServer发布package,然后本地项目引用,断点也能进入源码。

  我的第三种方式:将需要的源码全部下载,然后移除当前项目对该包的引用,然后添加对该项目的引用。

 6、AddMvcCoreServices实际就是把接口或者基类与派生类的对应关系添加到serviceCollection中。

7、设计程序的过程中,推荐以某一个类型的实例化为主线,在通过各个管道的过程中,给该类型的各个属性完成赋值过程。MVC Core中的主类就是MvcBuilder,只不过Service作为其属性,是先进行赋值,然后才创建该主类并将service赋值给该主类的service属性。

8、MVC启动类:WebHost   IServer实际是:Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer。

9、MVC中处理路由的类,实际上就两个:MvcRouteHandler和MvcAttributeRouteHandler,RouteCollection和Route类是对这两个类的包装。

10、启动完毕后,完毕是什么结果?  完毕状态应该是程序将所需要的所有组件都装载完毕,启动KestrelHttpServer在相应的端口上进行监听,有请求进来再交给Route相关的组件进行处理。在站点停止之前,程序一直停止在await host.WaitForTokenShutdownAsync(token);以等待站点停止,不然就一直等待。

11、中间件:

 12、在我们的启动文件配置的Configure方法中,添加了额外几个中间件

 app.UseDeveloperExceptionPage();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

app.UseMvc();

所以最终的管道如下图:

 13、

请求的处理路径:
由System.Threading下的ThreadPoolWorkQueue类的Dispatch方法来分发请求。
Microsoft.AspNetCore.Server.Kestrel.Core.dll中的HttpProtocol类的private async Task ProcessRequests<TContext>(IHttpApplication<TContext> application)来处理请求
从HostingApplication类的ProcessRequestAsync开始处理新的请求,依次经过各种已经提前注册好的中间件。
RequestServicesContainerMiddleware
ForwardedHeadersMiddleware
IISMiddleware
DeveloperExceptionPageMiddleware
HttpsRedirectionMiddleware
StaticFileMiddleware
CookiePolicyMiddleware
RouterMiddleware
调用中间件的Invoke方法

14、

管道是如何实现的?
WebHost的BuildApplication方法中,使用多层的Action<IApplicationBuilder>的嵌套完成中间件的初始化(最后是调用我们自己定义的DavidStartup类的Configure方法)
最终的管道都是存放在ApplicationBuilder类的_components中。

15、

ServiceCollectionServiceExtensions AddSingleton直接添加,如果是通过ServiceProvider的GetService方法,则实际调用ConcurrentDictionary的GetOrAdd方法,也就是有就取出来,没有就添加;ServiceCollectionDescriptorExtensions中的TryAddSingleton,是使用IServiceCollection对象来尝试添加,已经存在就不添加
ServiceProvider就是ServiceProvider这个类(Microsoft.Extensions.DependencyInjection)

16、

Router中间件只有在找不到handler的情况下才会让程序继续走下一个中间件,如果已经找到匹配的中间件则不会继续往下走,如果找不到handler,那么就是错误,不会接着走下去会调用如下默认中间件:
RequestDelegate app = context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
};//这个其实就是中间件

posted @ 2018-09-10 14:49  David.Cai1990  阅读(119)  评论(0)    收藏  举报