关于.NET Core学习
-->最新的版本:.NET-Core3.1 (以前的版本就不用看了)
建议:学习基础的原理和简单的应用-->以MVC5为基础,你就可以直接用了-->实践
务必学好.NET-Core在Linux平台的部署。
************************************第1章:.NET Core3.1跨平台基础与原理*************************************
一、.NET Core发展历程和Standard标准库
结论:使用合适的版本创建Standard标准库,可以在对应版本的Framework和Core中轻松的引用。
二、第一个AspNetCore程序
1、解释项目组成(.NET Core项目的5大部件)
【1】launchSettings.json :项目启动配置文件(核心,关键)会在项目启动开始加载。
【2】appsettings.json :应用程序自己的配置文件(通常是根据项目的要求自己设置的)支持热加载。
注意:和.NET Framework完全不一样的配置信息读取方式。
【3】Program.cs :控制台程序的入口类。
【4】Startup.cs :用来配置启动需要各种服务、应用程序的请求管道等配置类。
【5】wwwroot :静态文件夹,专门用来存储静态文件(图片、样式表、js文件等...)
注意:.NET Core中有两种路径。第一种就是web静态路径,第二就是项目的根目录。
2、启动程序观察程序执行的流程。
【1】程序启动最终的目的:在.NetCore项目中,程序启动后,经过一系列复杂的对象的创建、配置后,会得到一个
专门的web服务器(Host:宿主-->环境)(对比:以前.NET Framework阶段,是没有这个服务器的)。
说白了就是得到一个Host对象,并启动。这个web服务器能够运行在不同的操作系统上。
记住:在所有的web项目中,都会有这么一个“web服务器,即Host对象”。
【2】Host对象过于复杂,我们很难直接创建,所有按照“建造者模式”方式,通过一个其他的对象来帮助完成这个复杂
对象的创建。
【3】观察程序执行过程
当Build()方法被调用的时候,首先构建了Startup对象,其次调用了下面的方法:
public void ConfigureServices(IServiceCollection services)
{
}
记住:在.NET Core中,“一切皆注入”。在上面的方法中,用来注入项目所需要的各种服务。
一组服务:对象生命周期 接口 接口实现类
使用容器注册服务的好处,一般我们不需要自己new,直接通过容器可以获得对象。这样做的好处,后面大家会学到
关于依赖注入的方式。
对象生命周期(瞬时模式、单例模式、作用域模式)
当Run()方法被调用的时候,会执行下面的方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
在上面的方法中,注册项目需要的各种“请求管道模型”。
在.NET Core中为什么要这么设计呢?就是为了更好的提升系统的性能,与项目没有关系的所有服务,均不会使用。
总结:.NET以配置为中心的开发方式。
思考:服务如何自己注册?注册的服务有系统服务、有自定义服务。
管道模型究竟如何使用?
三、将项目改造成MVC程序
四、思考
AspNetCore程序是如何在windows上面部署的?如何实现了跨平台?
ApsNetCore程序是以控制台为启动方式,有什么好处?
************************************第2章:.NET Core3.1在Windows平台的部署和跨平台原理**********************
一、项目发布
1、项目发布到指定的路径文件夹。
2、通过控制台测试,如果项目启动没问题。就可以部署。
二、项目部署
1、IIS安装好
2、Runtime或者SDK3.1安装好 + 服务器组件(windows Server Hosting)
运行时:所有的服务器必须要安装(不同服务器操作系统,要选对版本)
现在我们为了开发的方便,我们直接安装SDK。会包括Runtime。
VS2019自带SDK,属于轻量级的。服务器的话,必须独立安装。
3、在IIS上部署
【1】基本的部署和Framework几乎是一样的。但是应用程序池必须选择“无托管”。
【2】浏览网站。
4、IIS组件解释
AspNetCoreModuleV2:这个模块其实就是我们前面安装的那个windows Server Hosting生成的文件。
AspNetCoreModuleV2:这个模块其实作为IIS的组件,负责HTTP请求的转发,并且只有转发。
转发给我们当前所部署的这个程序中通过控制台运行的web服务器(Host)。
三、对比分析
1、在.NET Framework阶段IIS的作用。
【1】所有的应用程序都会托管到w3wp.exe进程中。
【2】当请求进来的时候,IIS是HttpRuntime接受请求,并派发到对应的应用程序池和托管站点。
【3】所有的任务,其实都是IIS内部完成的。
2、发现问题
IIS从接受请求开始到响应返回,包揽了一切。意味着只有windows的IIS能够运行我们开发的程序。其他操作系统不行。
结论:所以在经典阶段,无法实现跨平台,就是因为这个原因。
3、在Asp.NetCore阶段IIS的作用变化
【1】运行位置:AspNetCore程序不是运行在IIS的工作进程中,而是独立在控制台程序中运行。
【2】启动方式:Kestrel服务器是通过dotnet命令启动的。(可以在部署的时候,有一个立即启动对勾)
【3】所起作用:AspNetCoreModule这个组件只是将请求转发到Kestrel这个内网服务器中,并做具体的处理。
也就是说,IIS其实就是一个反向代理服务器!
得出结论:AspNetCore能够跨平台,就是因为内置了Kestrel服务器,而不依赖于IIS托管。
在其他平台上,反向代理服务器还是非常容易得到的。
反向代理:用户---> 反向代理服务器-->防火墙-->服务器1\服务器2...
网络(远程服务器) <---代理服务器-- 防火墙<--用户1、用户2
继续思考:Kestrel服务器内部是什么样子?这时候我们就得分析相关的源码。
4、分析public static IHostBuilder CreateDefaultBuilder(string[] args)方法的源码
【1】创建了HostBuilder对象
【2】启动配置、应用程序配置、日志配置、默认的Ioc容器等。。。。
5、分析internal static void ConfigureWebDefaults(IWebHostBuilder builder)方法
【1】使用Kestrel服务器,并配置。
【2】使用IIS,启用集成代理。
public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, KestrelServerOptions> configureOptions)
{
return hostBuilder.UseKestrel().ConfigureKestrel(configureOptions);
}
public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder)
{
return hostBuilder.ConfigureServices((Action<IServiceCollection>)delegate(IServiceCollection services)
{
services.TryAddSingleton<IConnectionListenerFactory, SocketTransportFactory>();
services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>();
services.AddSingleton<IServer, KestrelServer>();
});
}
重点:services.AddSingleton<IServer, KestrelServer>();
得出:KestrelServer是以单例模式添加到服务容器中。
public class KestrelServer : IServer, IDisposable
{
}
这个类是Kestrel服务器的核心类。
思考:容器IServiceCollection在哪里?具体有什么用?怎么使用?
****************************************第3章:Ioc容器和依赖注入DI的使用****************************************
关于对象创建的问题引入:正常情况下,我们设计一个类,然后得到一个对象有几种方式?
1、直接new对象。直接耦合。
2、通过工厂和反射,把对象创建的控制权给工厂。我们使用者不用关心对象是如何出来的。
以上方法都是为了得到对象。如果这个对象创建比较复杂,还行不行?
一、Ioc容器使用的必要性
1、创建一组接口和服务
2、创建一组对象
3、发现问题:当我们创建一个对象,如果这个对象有其他的依赖对象,则必须先把依赖对象创建出来,然后才能构建。
4、思考问题:这种依赖关系对我们开发非常的麻烦,有没有一种方法,让我们开发者,只关心接口,不用关心对象是
如何创建的呢?
解决问题:使用Ioc容器,轻松搞定!
总结:依赖注入(DI)就是IOC这个理念一种实现方式,有了DI,对象就不有你直接去new了,你就负责声明就行了,你声明了一声了,就意味着对着框架大喊了一声:“我要这个对象”,这个时候框架就帮你New了一个对象,你安心地把对象的创建交给框架就行了。