ASP.NET Core Basic 1-1 WebHost与项目配置
.NET Core ASP.NET Core Basic 1-1
本节内容为WebHost与项目配置
项目配置文件
我们可以很清楚的发现在我们的文件中含有一个Json文件——appsettings.json,实际上,这个文件就是我们项目的默认配置文件,它内部含有了默认的一些设置,当然你也可以自己进行添加或者修改。这里我们不展开讲述。我们会在本文的后部分进行讲解如何读取、操作配置文件。
项目主入口Program
在ASP.NET Core2.X的空项目中,你会发现有以下两个类存在——StarUp、Program,其中Program类里面就是我们ASP.NET Core的入口(Main函数)。我们可以看一下Program类
namespace ASP.NET_Core_Study
{
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中使用了一个 CreateWebHostBuilder 函数进行程序的初始化,里面就涉及到了我们的WebHost。
那么什么是WebHost呢?你可以简单的理解为就是我们的Web项目的服务主机,它是ASP.NET Core的核心,它调用了CreateDefaultBuilder方法进行创建。而泛型函数使用的StartUp则是我们服务的配置类。
当然,WebHost进行服务主机创建的时候你也可以使用 WebHost.Start() 进行手动的配置与创建。这里我们只针对官方默认的方法进行学习与分析。
首先看到CreateDefaultBuilder()的源码,这个你可以在Github或者是ReSharp的反编译功能查看到,这里我是直接从GitHub公开的源码复制
/// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class with pre-configured defaults.
/// </summary>
/// <remarks>
/// The following defaults are applied to the returned <see cref="WebHostBuilder"/>:
/// use Kestrel as the web server and configure it using the application's configuration providers,
/// set the <see cref="IHostingEnvironment.ContentRootPath"/> to the result of <see cref="Directory.GetCurrentDirectory()"/>,
/// load <see cref="IConfiguration"/> from 'appsettings.json' and 'appsettings.[<see cref="IHostingEnvironment.EnvironmentName"/>].json',
/// load <see cref="IConfiguration"/> from User Secrets when <see cref="IHostingEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,
/// load <see cref="IConfiguration"/> from environment variables,
/// load <see cref="IConfiguration"/> from supplied command line args,
/// configure the <see cref="ILoggerFactory"/> to log to the console and debug output,
/// and enable IIS integration.
/// </remarks>
/// <param name="args">The command line args.</param>
/// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder();
if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
{
builder.UseContentRoot(Directory.GetCurrentDirectory());
}
if (args != null)
{
builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
}
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
}).
UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
ConfigureWebDefaults(builder);
return builder;
}
你在这里可以非常清楚的看到,这个函数他会取寻找appsettings.json以及appsettings.{env.EnvironmentName}.json。因此在使用默认的方法进行项目实战时,我们不应该修改这个文件的文件名。并且我们可以发现,这个文件是分两部分的,一部分是我们的发布版本(publish),一部分是我们的开发版本。他们的文件名是不同的,在源码中我们也可以找到这些语句。同时我们的builder调用了UseConfiguration方法,这是一个参数配置的方法,用于接收我们从控制台输入的一些参数。
并且,我们可以看到他还进行了服务的替换UseDefaultServiceProvider以及根目录的设置UseContentRoo,源码如下
public static IWebHostBuilder UseContentRoot(this IWebHostBuilder hostBuilder, string contentRoot)
{
if (contentRoot == null)
throw new ArgumentNullException(nameof (contentRoot));
return hostBuilder.UseSetting(WebHostDefaults.ContentRootKey, contentRoot);
}
public IWebHostBuilder UseSetting(string key, string value)
{
this._config[key] = value;
return (IWebHostBuilder) this;
}
说到这里,我需要引出我们ASP.NET Core的两种启动方式。一种是使用我们微软官方的IIS进行项目的部署,他的本质是将dll注入到IIS服务中。当然,我们知道IIS是Windows上的Web服务器,如果我们要进行跨平台的开发,我们可以使用微软开发的Kestrel,源码中的ConfigureWebDefaults函数的源码我们就可以看到相关的操作
internal static void ConfigureWebDefaults(IWebHostBuilder builder)
{
builder.UseKestrel((builderContext, options) =>
{
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})
.ConfigureServices((hostingContext, services) =>
{
// Fallback
services.PostConfigure<HostFilteringOptions>(options =>
{
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
services.AddRouting();
})
.UseIIS()
.UseIISIntegration();
}
我们可以发现,在这里,它会从配置文件中读取相关的配置进行配置我们启动使用的服务选项。UseKestrel函数对一些服务进行了注册,以便后续的使用。这里我不打算进行详细的讲解,因为这一节内容只是希望你能够对项目的启动有一个初步的认识,你需要知道的是,目前位置,我们发现了ASP.NET Core程序会在实例化WebHost之前配置好一切,并且我们可以使用一个开源跨平台的Web服务器Kestrel。
StartUp
StartUp类是一个配置性质的类,它里面有Configure(IApplicationBuilder app, IHostingEnvironment env)以及ConfigureServices(IServiceCollection services)方法,这两个方法中ConfigureServices是我们的服务配置方法或者说是容器配置,它主要用于配置我们依赖注入的类,而Configure方法是我们配置中间件的地方,这两个概念我会在后一两篇文章中进行非常详细的讲解。
总结
本篇文章内容并不是很多,主要是让你知道ASP.NET Core其实只是一个简答的控制台程序,只是它调用了一些服务而已。
总体来说我们ASP.NET Core的WebHost创建的过程是
- 配置好服务器UseKestrel()
- 配置好根目录UseContentRoot()
- 添加配置文件源ConfigureAppConfiguration((context, builder) => builder.AddJsonFile("appsetting.json", true, true))
- 注册日志记录到控制台ConfigureLogging(builder => builder.AddConsole())
- 配置好StartUp类,进行依赖注入和中间件的配置UseStartup()
- 生成WebHost,Build()返回一个WebHost对象
- 运行WebHost,Run()将WebHost启动
当然IWebHostBuilder接口也有一些其他的常见方法,这里我做一个简单的列举
- UseUrls,配置启动的Ip地址
- UseSetting,使用新的文件替换默认appsettings.json
- UseShutdownTimeout,自动关机
- UseEnvironment,配置启动时的环境(生产Or开发)
这几个是我经常使用的函数,其他的函数你可以在微软官方API文档或者是ASP.NET Core的源码中进行学习,并不难。
Reference
如果我的文章帮助了您,请您在github.NETCoreGuide项目帮我点一个star,在博客园中点一个关注和推荐。
ASP.NET Core Basic 1-1 WebHost与项目配置的更多相关文章
- .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入
.NET Core ASP.NET Core Basic 1-2 本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样 ...
- 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问
中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...
- Asp.Net Core轻松入门之WebHost的配置
在本篇文章中,我来讲一讲如何利用WebHost来加载配置文件和设置启动的Url 在前面的文章中讲过,ASP.Net Core应用程序会自动加载appsettings.json中的配置文件,那么如果配置 ...
- 我心中的ASP.NET Core 新核心对象WebHost(二)
这是ASP.NET Core新核心对象系列的第二篇,上一篇 WebHost准备阶段 我们讲到了WebHostBuilder的初始化及配置.我们给WebHostBuilder进行以下配置 UseKest ...
- 【ASP.NET Core快速入门】(六)配置的热更新、配置的框架设计
配置的热更新 什么是热更新:一般来说,我们创建的项目都无法做到热更新:即项目无需重启,修改配置文件后读取到的信息就是修改配置之后的 我们只需要吧项目中用到的IOptions改成IOptionsSnap ...
- Asp.net Core Startup Class中是如何获取配置信息的
默认的网站构建方式 VS2015新建asp.net core项目,项目建立完成后,有两个文件,Program.cs和Startup.cs. public class Program { public ...
- 解决ASP.NET Core通过docker-compose up启动应用无法配置https的解决办法
错误重现一下: 新建了一个ASP.NET Core应用,在VS2017下添加Docker支持,选择Linux环境 然后再给这个web应用再右键添加容器业务流程协调程序支持,然后解决方案就多了一个doc ...
- ASP.NET Core 2.2 : 二十三. 深入聊一聊配置的内部处理机制
上一章介绍了配置的多种数据源被注册.加载和获取的过程,本节看一下这个过程系统是如何实现的.(ASP.NET Core 系列目录) 一.数据源的注册 在上一节介绍的数据源设置中,appsettings. ...
- ASP.NET Core 入门笔记2,建立项目
1.建立项目 2.项目结构 1.项目结构说明 根目录/文件 说明 .vscode目录 VS Code项目配置目录,相当于.vs..idea文件夹 bin目录 编译输出目录 obj目录 编译配置与中间目 ...
随机推荐
- Android studio 混淆打包安装后报错NullPointerException int java.util.List.size()
菜鸟的我,尝试混淆打包app...打包之前没有什么问题,混淆打包之后遇到各种问题.首先,感谢原博主的分享.解决了我的问题.谢谢. 原文地址:http://blog.csdn.net/tou_star/ ...
- python 之 并发编程(线程理论,开启线程的两种方式,进程与线程的区别,线程对象的其他方法)
9.9 线程理论 1.什么是线程 线程指的是一条流水线的工作过程 进程根本就不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位 2.进程VS线程 同一进程内的线程们共享 ...
- Atom实用插件
下载atom狠戳本链接 中文简体插件(工具栏,右键菜单,设置菜单) simplified-chinese-menu 代码格式化插件(支持多种语言) atom-beautify 智能补全资源路径插件 a ...
- 第一次使用cnblog,希望大佬们多多指教
我目前在学习ML和DeepLearning,在这里和大家共同成长
- 《VR入门系列教程》之10---3D图形学初识
第三章 基于Oculus Rift开发桌面端VR应用 接下来的几个章节中我们会进行VR开发的实际操练,本章就从Oculus Rift开发开始,我们会介绍如何开发一个桌面端的VR应用.虽然只是介 ...
- php 常用函数总汇
php 使用命令行函数exec($sql,$result,$status); $sql 命令 $result 返回东西 $status成功与否的状态 例如: php使用命令行去执行数据库备份( ...
- Redis 学习笔记(篇六):数据库
Redis 是一个使用 C 语言编写的 NoSql 的数据库,本篇就讲解在 Redis 中数据库是如何存储的?以及和数据库有关的一些操作. Redis 中的所有数据库都保存在 redis.h/redi ...
- windows 下搭建安装 sass
众所周知,sass 解析需要有 ruby 的支撑,所以, 第一步:点我下载 ruby: 第二步:安装 ruby: 在安装 ruby 过程中需要注意的一点:把 ruby 执行文件添加到 path,勾选这 ...
- .NET Core CSharp初级篇 类的生命历程
.NET Core CSharp初级篇 1-7 本节内容为类的生命周期 引言 对象究竟是一个什么东西?对于许多初学者而言,对象都是一个非常抽象的知识点.如果非要用一句话描述,我觉得"万物皆对 ...
- 初探java流操作
在处理集合时,我们通常会迭代遍历它的元素,并从每个元素上执行某项操作.例如,假设我们想要对某本书中的所有长单词进行计数.首先我们要将所有单词放入一个列表中: String contents = new ...