ASP.NET Core 系列[1]:ASP.NET Core 初识
ASP.NET Core 是一个跨平台的高性能开源框架,是一个用于连接到互联网的基于云的现代应用程序。 ASP.NET Core 用于构建如 Web 应用、物联网(IoT)应用和移动后端应用,这些应用可以在 .NET Core 或 .NET Framework上运行,你可以在 Windows、Mac 和 Linux 上跨平台的开发和运行你的 ASP.NET Core 应用。
ASP.NET Core项目解读
由于相比以前传统的ASP.NET项目而言, ASP.NET Core 的项目结构也变的完全不同,对于刚接触 ASP.NET Core 的小白来讲,我觉得有必要来简单解读一下。
注:这里的解读是针对ASP.NET Core 2.1
项目文件夹总预览
Program类
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
} public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
我们可以看到程序中有一个 Program 类型,按照我们以前的认知,这个类不是只出现在控制台项目中的嘛。那么接下来我们来看看这个类里面都有些什么,又都干了什么。
WebHost
webHost相当于一个用Socket实现的Web服务。
1、WebHost使用了建造者模式
2、CreateDefaultBuilder:我们用反编译工具来查看下这个方法里面都干了什么。
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
IWebHostBuilder arg_31_0 = new WebHostBuilder();
Action<WebHostBuilderContext, KestrelServerOptions> arg_31_1;
if ((arg_31_1 = WebHost.<>c.<>9__8_0) == null)
{
arg_31_1 = (WebHost.<>c.<>9__8_0 = new Action<WebHostBuilderContext, KestrelServerOptions>(WebHost.<>c.<>.<CreateDefaultBuilder>b__8_0));
}
IWebHostBuilder arg_70_0 = HostingAbstractionsWebHostBuilderExtensions.UseContentRoot(WebHostBuilderKestrelExtensions.UseKestrel(arg_31_0, arg_31_1), Directory.GetCurrentDirectory()).ConfigureAppConfiguration(delegate(WebHostBuilderContext hostingContext, IConfigurationBuilder config)
{
IHostingEnvironment hostingEnvironment = hostingContext.get_HostingEnvironment();
JsonConfigurationExtensions.AddJsonFile(JsonConfigurationExtensions.AddJsonFile(config, "appsettings.json", true, true), string.Format("appsettings.{0}.json", hostingEnvironment.get_EnvironmentName()), true, true);
if (HostingEnvironmentExtensions.IsDevelopment(hostingEnvironment))
{
Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.get_ApplicationName()));
if (assembly != null)
{
UserSecretsConfigurationExtensions.AddUserSecrets(config, assembly, true);
}
}
EnvironmentVariablesExtensions.AddEnvironmentVariables(config);
if (args != null)
{
CommandLineConfigurationExtensions.AddCommandLine(config, args);
}
});
Action<WebHostBuilderContext, ILoggingBuilder> arg_70_1;
if ((arg_70_1 = WebHost.<>c.<>9__8_2) == null)
{
arg_70_1 = (WebHost.<>c.<>9__8_2 = new Action<WebHostBuilderContext, ILoggingBuilder>(WebHost.<>c.<>.<CreateDefaultBuilder>b__8_2));
}
IWebHostBuilder arg_94_0 = WebHostBuilderExtensions.ConfigureLogging(arg_70_0, arg_70_1);
Action<WebHostBuilderContext, IServiceCollection> arg_94_1;
if ((arg_94_1 = WebHost.<>c.<>9__8_3) == null)
{
arg_94_1 = (WebHost.<>c.<>9__8_3 = new Action<WebHostBuilderContext, IServiceCollection>(WebHost.<>c.<>.<CreateDefaultBuilder>b__8_3));
}
IWebHostBuilder arg_BD_0 = WebHostBuilderIISExtensions.UseIISIntegration(arg_94_0.ConfigureServices(arg_94_1));
Action<WebHostBuilderContext, ServiceProviderOptions> arg_BD_1;
if ((arg_BD_1 = WebHost.<>c.<>9__8_4) == null)
{
arg_BD_1 = (WebHost.<>c.<>9__8_4 = new Action<WebHostBuilderContext, ServiceProviderOptions>(WebHost.<>c.<>.<CreateDefaultBuilder>b__8_4));
}
IWebHostBuilder webHostBuilder = WebHostBuilderExtensions.UseDefaultServiceProvider(arg_BD_0, arg_BD_1);
if (args != null)
{
HostingAbstractionsWebHostBuilderExtensions.UseConfiguration(webHostBuilder, CommandLineConfigurationExtensions.AddCommandLine(new ConfigurationBuilder(), args).Build());
}
return webHostBuilder;
}
以下是Action<WebHostBuilderContext, KestrelServerOptions> arg_31_1;委托的逻辑
internal void <CreateDefaultBuilder>b__8_0(WebHostBuilderContext builderContext, KestrelServerOptions options)
{
options.Configure(builderContext.get_Configuration().GetSection("Kestrel"));
}
以下是Action<WebHostBuilderContext, IServiceCollection> arg_94_1;委托的逻辑
internal void <CreateDefaultBuilder>b__8_3(WebHostBuilderContext hostingContext, IServiceCollection services)
{
WebHost.<>c__DisplayClass8_1 <>c__DisplayClass8_ = new WebHost.<>c__DisplayClass8_1();
<>c__DisplayClass8_.hostingContext = hostingContext;
OptionsServiceCollectionExtensions.PostConfigure<HostFilteringOptions>(services, new Action<HostFilteringOptions>(<>c__DisplayClass8_.<CreateDefaultBuilder>b__5));
ServiceCollectionServiceExtensions.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(services, new ConfigurationChangeTokenSource<HostFilteringOptions>(<>c__DisplayClass8_.hostingContext.get_Configuration()));
ServiceCollectionServiceExtensions.AddTransient<IStartupFilter, HostFilteringStartupFilter>(services);
}
以下是Action<WebHostBuilderContext, ServiceProviderOptions> arg_BD_1;委托的逻辑
internal void <CreateDefaultBuilder>b__8_4(WebHostBuilderContext context, ServiceProviderOptions options)
{
options.set_ValidateScopes(HostingEnvironmentExtensions.IsDevelopment(context.get_HostingEnvironment()));
}
以下是Action<WebHostBuilderContext, ILoggingBuilder> arg_70_1委托的逻辑
internal void <CreateDefaultBuilder>b__8_2(WebHostBuilderContext hostingContext, ILoggingBuilder logging)
{
LoggingBuilderExtensions.AddConfiguration(logging, hostingContext.get_Configuration().GetSection("Logging"));
logging.AddConsole();
DebugLoggerFactoryExtensions.AddDebug(logging);
}
由以上代码我们可以得出以下结论:
a.添加Kestrel和IIS的web服务器
b.添加Configuration配置系统
支持 appsettings.json 和多环境的 appsettings.{0}.json
支持CommandLine
c.添加日志系统(这里通过反编译WebHostBuilderExtensions扩展类,可以知道是调用了IServiceCollection的AddLogging扩展方法,然后我们转到 LoggingServiceCollectionExtensions扩展类,找到AddLogging扩展方法,然后将日志注入到IServiceCollection)
默认添加对Console和Debug的输出
3、UseStartup:通过反编译查看源代码
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)
{
string str = IntrospectionExtensions.GetTypeInfo(startupType).get_Assembly().GetName().get_Name();
return hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, str).ConfigureServices(delegate (IServiceCollection services) {
if (IntrospectionExtensions.GetTypeInfo((Type) typeof(IStartup)).IsAssignableFrom(IntrospectionExtensions.GetTypeInfo(startupType)))
{
services.AddSingleton(typeof(IStartup), startupType);
}
else
{
services.AddSingleton(typeof(IStartup), delegate (IServiceProvider sp) {
IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>();
return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName));
});
}
});
}
由上代码可得出结论:最终将Startup类添加到服务中。
4、Build:反编译查看源代码
public IWebHost Build()
{
AggregateException exception;
IWebHost host2;
if (this._webHostBuilt)
{
throw new InvalidOperationException(Microsoft.AspNetCore.Hosting.Resources.WebHostBuilder_SingleInstance);
}
this._webHostBuilt = true;
IServiceCollection serviceCollection = this.BuildCommonServices(out exception);
IServiceCollection services = serviceCollection.Clone();
IServiceProvider provider = <Build>g__GetProviderFromFactory|13_0(serviceCollection);
if (!this._options.SuppressStatusMessages)
{
if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
{
Console.WriteLine("The environment variable 'Hosting:Environment' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
{
Console.WriteLine("The environment variable 'ASPNET_ENV' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS") != null)
{
Console.WriteLine("The environment variable 'ASPNETCORE_SERVER.URLS' is obsolete and has been replaced with 'ASPNETCORE_URLS'");
}
}
ILogger<WebHost> requiredService = provider.GetRequiredService<ILogger<WebHost>>();
foreach (IGrouping<string, string> grouping in from g in Enumerable.GroupBy<string, string>(this._options.GetFinalHostingStartupAssemblies(), delegate (string a) {
return a;
}, (IEqualityComparer<string>) StringComparer.get_OrdinalIgnoreCase()) select g)
{
requiredService.LogWarning(string.Format("The assembly {0} was specified multiple times. Hosting startup assemblies should only be specified once.", grouping), Array.Empty<object>());
}
this.AddApplicationServices(services, provider);
WebHost host = new WebHost(services, provider, this._options, this._config, exception);
try
{
host.Initialize();
host2 = host;
}
catch
{
host.Dispose();
throw;
}
return host2;
}
由以上代码可以看出,该方法就是用来初始化操作的。
a.初始化了服务容器(BuildCommonServices这个方法中初始化容器时,注册了大把的服务)
b.初始化了WebHost(host.Initialize();)
c.我们反编译一个Initialize方法, this._startup = this._hostingServiceProvider.GetService<IStartup>(); 最终可以看到,是从服务中获取的。那么是时候
注入进去的呢,当然是UseStartup<T>这个方法注入的。
5、Run
这个方法就是用来运行Web应用程序并阻止调用线程,直到host停止。因为在运行之前要做很多的事情。(在启动之前做了无数的事情)
Startup类
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
1、ConfigureServices:这个方法是运行是调用的,使用这个方法为程序的服务容器添加服务的
a.上面已经讲过,在Program类中的IWebHostBuilder中的Build()方法里面,程序初始化服务容器的时候就已经为我们添加了许多的服务,所以说,这个方法只是为了给开发
人员进行扩展。
2、Configure:这个方法是运行是调用的,这个方法是用来配置HTTP请求管道的
a.可以在管道中添加自定义或者Microsoft封装好的中间件
b.可以根据环境的不同,选择不同的中间件
通过编译追踪,最终调用的是IApplicationBuilder中的Use(Func<RequestDelegate, RequestDelegate> middleware);方法,而这个方法做的事情就是,将中间件添加到这个类型
的_components集合中。反编译代码如下:
private readonly IList<Func<RequestDelegate, RequestDelegate>> _components; public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
this._components.Add(middleware);
return this;
}
launchSettings.json启动文件
解决问题:快速的做环境切换,方便开发和调试
为了让你的程序在多环境一样保持稳定
wwwroot
用来存放静态资源。
ASP.NET Core 系列[1]:ASP.NET Core 初识的更多相关文章
- 【深入ASP.NET原理系列】--ASP.NET页面生命周期
前言 ASP.NET页面运行时候,页面将经历一个生命周期,在生命周期中将执行一系列的处理步骤.包括初始化.实例化控件.还原和维护状态.运行时间处理程序代码以及进行呈现.熟悉页面生命周期非常重要,这样我 ...
- 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制
微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...
- 【asp.net core 系列】14 .net core 中的IOC
0.前言 通过前面几篇,我们了解到了如何实现项目的基本架构:数据源.路由设置.加密以及身份验证.那么在实现的时候,我们还会遇到这样的一个问题:当我们业务类和数据源越来越多的时候,我们无法通过普通的构造 ...
- .net core系列之《.net core内置IOC容器ServiceCollection》
一.IOC介绍 IOC:全名(Inversion of Control)-控制反转 IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们 ...
- .net core系列之《.net core中使用集成IDistributedCache接口的Redis和MongoDB实现分布式缓存》
分布式的缓存可以提高性能和可伸缩性的 ASP.NET Core 应用程序,尤其是托管在云中或服务器场中时. 什么是分布式的缓存 分布式的缓存由多个应用程序服务器共享,缓存中的信息不存储在单独的 Web ...
- 【深入ASP.NET原理系列】--Asp.Net Mvc和Asp.Net WebForm共用一套ASP.NET请求管道
.NET FrameWork4在系统全局配置文件(如在如下目录中C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config) 中添加了一个名字叫Url ...
- .net core系列之《.net core中使用MySql以及Dapper》
当我们决定使用.Net Core开发的时候,就放弃使用SqlServer的打算吧.那应该选择哪个数据库呢?一般选择MySql的比较多. 接下来我们来演示在.Net Core中使用MySQL吧. 1.原 ...
- 【深入ASP.NET原理系列】--Asp.Net Mvc和Asp.Net WebForm实际上共用一套ASP.NET请求管道
.NET FrameWork4在系统全局配置文件(如在如下目录中C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config) 中添加了一个名字叫Url ...
- 一个官翻教程集合:ASP.NET Core 和 EF Core 系列教程
通过一个大学课程案例讲解了复杂实体的创建过程及讲解 1.ASP.NET Core 和 Entity Framework Core 系列教程——入门 (1 / 10) 2.ASP.NET Core 和 ...
- 【目录】asp.net core系列篇
随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...
随机推荐
- 【数组】Maximum Subarray
题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...
- 【转】Spark源码分析之-Storage模块
原文地址:http://blog.csdn.net/aiuyjerry/article/details/8595991 Storage模块主要负责数据存取,包括MapReduce Shuffle中间结 ...
- 带你了解数据库中事务的ACID特性
前言 前面我们介绍过数据库中 带你了解数据库中JOIN的用法 与 带你了解数据库中group by的用法的相关用法.本章节主要来介绍下数据库中一个非常重要的知识点事务,也是我们项目中或面试中经常会遇到 ...
- 基于TrueLicense实现产品License验证功能
受朋友所托,需要给产品加上License验证功能,进行试用期授权,在试用期过后,产品不再可用. 通过研究调查,可以利用Truelicense开源框架实现,下面分享一下如何利用Truelicense实现 ...
- mongodb与关系型数据库优缺点比较
1.与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度②文档结构的存储方式,能够更便捷的获取数据③内置GridFS,支持大容量的存储.④内置Sharding.⑤第 ...
- 02-python基本数据类型
python的变量不需要声明, 但变量使用前必须复制, 因为python中所有的内容全部是对象 变量是没有类型的, 有类型的是指向内存对象的类型 a = ' a = 是合法的 此外, python还可 ...
- springcloud-06-feign的使用
在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Ap ...
- 桌面程序开发入门(WinForm with C#)
1.使用Visual Studio 2013创建新项目 2.创建一个主窗体和4个子窗体 3.创建一个数据库.一个表.一个存储过程 4.在配置文件里添加数据库连接字符串 5.真正的编码工作. 第一步:创 ...
- CSS3设置Table奇数行和偶数行样式
table:.myTable tr:nth-child(even){ //偶数行 background:#fff;}.myTable tr:nth-child(odd){ //奇数行 backgrou ...
- 任务四十:UI组件之日历组件(一)
任务四十:UI组件之日历组件(一) 面向人群: 有一定基础的同学 难度: 中 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习 ...