入口程序

如果做过Web之外开发的人,应该记得这个是标准的Console或者Winform的入口。为什么会这样呢?

.NET Web Development and Tools Blog

ASP.NET Core is a console app In RC1 an ASP.NET application was a class library that contained a Startup.cs class. When the DNX toolchain run your application ASP.NET hosting libraries would find and execute the Startup.cs, booting your web application. Whilst the spirit of this way of running an ASP.NET Core application still exists in RC2, it is somewhat different.

As of RC2 an ASP.NET Core application is a .NET Core Console application that calls into ASP.NET specific libraries. What this means for ASP.NET Core apps is that the code that used to live in the ASP.NET Hosting libraries and automatically run your startup.cs now lives inside a Program.cs. This alignment means that a single .NET toolchain can be used for both .NET Core Console applications and ASP.NET Core applications. It also means that customers have more obvious control over the code that hosts and runs their ASP.NET Core app:

翻译过来的意思大概是:

ASP.NET Core 在RC1的时候,是一个Console 应用程序,一个ASP.NET程序是一个包含有Startup.cs的类的类库。

当DNX(.NET运行环境)运行你的ASP.NET程序,它将会尝试去找到并且运行你的Stratup类,启动你的网站程序。这种启动方法任然在RC2中保留了下来,但是多少有些不同。

因为RC2是所谓的ASP.NET Core的应用程序,它是一种.NET Core 控制台(Console)程序,他被一些ASP.NET特殊的类所调用。这就意味着 ASPNET Core 原来存活在ASP.NET宿主库里面,自动执行Startup.cs的机制有所变化。

RC2的ASPNET Core变成了存活在一个控制台(Console)程序的程序,所有由Program.cs作为调用的入口了。

这样的话,整个.NET的工具链就变得内部执行机制统一了,即可以执行普通的 .NET Core Console 程序,也可以执行ASP.NET Core程序。

对于开发者和用户来说,也带来了一些控制和管理上的灵活性。

  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. var host = new WebHostBuilder()
  6. .UseKestrel()
  7. .UseContentRoot(Directory.GetCurrentDirectory())
  8. .UseIISIntegration()
  9. .UseStartup<Startup>()
  10. .Build();
  11. host.Run();
  12. }
  13. }

这里反复强调了一个宿主的概念。原来的MVC5时代,宿主应该是IIS服务器。

现在MVC6时代,宿主变成了一个普通的控制台程序了。当然,Web程序毕竟是需要一个WebHost运行环境的。UseKestrel,UseIISIntegration就是这样的环境。如果从Beta版开始关注的话,应该对于Kestrel不陌生,这个东西是一个迷你的HTTP服务器,可以让ASP程序HOST在上面运行。

注意:KestrelHttpServer,如果Baidu的话,一般出现这样的结果。请使用完整的关键字进行查询。

Kestrel 是 Scala 的一个非常小的队列系统,基于 starling。

KestrelHttpServer

Startup.cs

启动的前三句,分别涉及到Kestrel服务器,IIS集成,ContentRoot(内容的根目录,这里多说一句,现在的工程,解决方案的概念开始弱化了,取而代之的是文件夹的概念。可能和Nodejs的兴起有关。代码的组织形式更加自由了)

第四句则是和StartUp有关。

StartUp泛型

这里的StartUp虽然使用了泛型,但是如果看一下方法定义:TStartup只是约束为class

  1. //
  2. // Summary:
  3. // Specify the startup type to be used by the web host.
  4. //
  5. // Parameters:
  6. // hostBuilder:
  7. // The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
  8. //
  9. // Type parameters:
  10. // TStartup:
  11. // The type containing the startup methods for the application.
  12. //
  13. // Returns:
  14. // The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
  15. public static IWebHostBuilder UseStartup<TStartup>(this IWebHostBuilder hostBuilder) where TStartup : class;

我们来看一下StartUp里面到底做了什么

  1. public Startup(IHostingEnvironment env)
  2. {
  3. var builder = new ConfigurationBuilder()
  4. .SetBasePath(env.ContentRootPath)
  5. .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  6. .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
  7. if (env.IsDevelopment())
  8. {
  9. // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
  10. builder.AddUserSecrets();
  11. }
  12. builder.AddEnvironmentVariables();
  13. Configuration = builder.Build();
  14. }

SetBasePath,还是要设定一下全局的路径。还记得MVC5的时代,Server.Map方法,将虚拟路径和实际路径进行转换,我猜测这里也是为了这样的方法做准备。

AddJsonFile,这个就是将JSON文件格式的配置文件放入总的配置管理器中。

具体的配置问题,请参看下面这篇文章

(1-2)配置的升级 - ASP.NET从MVC5升级到MVC6

AddUserSecrets,这个是RC新的配置。

以下引用自 解读ASP.NET 5 & MVC6系列(5):Configuration配置信息管理 更多UserSecrets,请阅读原文。

敏感信息配置(RC版新增功能)

在RC版发布以后,微软又新增了一种敏感信息配置实现,程序集为Microsoft.Framework.ConfigurationModel.UserSecrets,通过该程序集的管理,我们可以将敏感的配置信息放在计算机的特殊目录下的secrets.json文件,其目录定义规则如下:

Windows: %APPDATA%\microsoft\UserSecrets<applicationId>\secrets.json

Linux: ~/.microsoft/usersecrets/\secrets.json

Mac: ~/.microsoft/usersecrets/\secrets.json

AddEnvironmentVariables:可以将操作系统的环境变量添加到配置系统中,同时你也可以对这些环境变量进行自定义

添加服务

除了StartUp方法,下面两个方法也是被系统(Runtime)自动调用的。

  1. // This method gets called by the runtime. Use this method to add services to the container.
  2. public void ConfigureServices(IServiceCollection services)
  3. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  4. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

和整个系统相关的,有两件事情,一个是系统提供什么服务,当然这里是你可以自定义的,还有一件事情是,系统要怎么做LOG日志。

虽然这样说并不能很好的解释上面两个方法,但是大概就是这么回事。当然配置里面日志只是一个项目,MVC路由也可以作为配置项写在Configure里面的。

打开WebHostBuilder的源代码:这里就关心两件事情Service和Logger:服务和日志

(小知识,阶层型的配置文件,现在用冒号表示阶层关系了)

  1. namespace Microsoft.AspNetCore.Hosting
  2. {
  3. /// <summary>
  4. /// A builder for <see cref="IWebHost"/>
  5. /// </summary>
  6. public class WebHostBuilder : IWebHostBuilder
  7. {
  8. private readonly IHostingEnvironment _hostingEnvironment;
  9. private readonly List<Action<IServiceCollection>> _configureServicesDelegates;
  10. private readonly List<Action<ILoggerFactory>> _configureLoggingDelegates;
  11. private IConfiguration _config = new ConfigurationBuilder().AddInMemoryCollection().Build();
  12. private ILoggerFactory _loggerFactory;
  13. private WebHostOptions _options;
  14. /// <summary>
  15. /// Initializes a new instance of the <see cref="WebHostBuilder"/> class.
  16. /// </summary>
  17. public WebHostBuilder()
  18. {
  19. _hostingEnvironment = new HostingEnvironment();
  20. _configureServicesDelegates = new List<Action<IServiceCollection>>();
  21. _configureLoggingDelegates = new List<Action<ILoggerFactory>>();
  22. // This may end up storing null, but that's indistinguishable from not adding it.
  23. UseSetting(WebHostDefaults.EnvironmentKey, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
  24. // Legacy keys, never remove these.
  25. ?? Environment.GetEnvironmentVariable("Hosting:Environment")
  26. ?? Environment.GetEnvironmentVariable("ASPNET_ENV"));
  27. if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
  28. {
  29. Console.WriteLine("The environment variable 'Hosting:Environment' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
  30. }
  31. if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
  32. {
  33. Console.WriteLine("The environment variable 'ASPNET_ENV' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
  34. }
  35. }

服务的添加

  1. // This method gets called by the runtime. Use this method to add services to the container.
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4. // Add framework services.
  5. services.AddDbContext<ApplicationDbContext>(options =>
  6. options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  7. services.AddIdentity<ApplicationUser, IdentityRole>()
  8. .AddEntityFrameworkStores<ApplicationDbContext>()
  9. .AddDefaultTokenProviders();
  10. services.AddMvc();
  11. // Add application services.
  12. services.AddTransient<IEmailSender, AuthMessageSender>();
  13. services.AddTransient<ISmsSender, AuthMessageSender>();
  14. }

这里顾名思义:

  • AddDbContext:数据库服务
  • AddIdentity:身份认证服务
  • AddMvc:MVC核心服务
  • IEmailSender,ISmsSender :邮件和短信服务

配置

  1. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  2. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  3. {
  4. loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  5. loggerFactory.AddDebug();
  6. if (env.IsDevelopment())
  7. {
  8. app.UseDeveloperExceptionPage();
  9. app.UseDatabaseErrorPage();
  10. app.UseBrowserLink();
  11. }
  12. else
  13. {
  14. app.UseExceptionHandler("/Home/Error");
  15. }
  16. app.UseStaticFiles();
  17. app.UseIdentity();
  18. // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
  19. app.UseMvc(routes =>
  20. {
  21. routes.MapRoute(
  22. name: "default",
  23. template: "{controller=Home}/{action=Index}/{id?}");
  24. });
  25. }
  • loggerFactory:日志
  • UseStaticFiles :静态文件 (注意:有些文件还是需要在WebConfig里面配置的,例如JSON,字体文件等等,不然估计还是404错误)
  • UseIdentity:身份识别
  • UseMvc:路由(核心中的核心功能)

EnvironmentName

还有一个问题是系统是如何获得EnvironmentName的。


  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System.Collections.Generic;
  4. using Microsoft.AspNet.FileSystems;
  5. using Microsoft.Framework.Runtime;
  6. namespace Microsoft.AspNet.Hosting
  7. {
  8. public class HostingEnvironment : IHostingEnvironment
  9. {
  10. private const string DefaultEnvironmentName = "Development";
  11. public HostingEnvironment(IApplicationEnvironment appEnvironment, IEnumerable<IConfigureHostingEnvironment> configures)
  12. {
  13. EnvironmentName = DefaultEnvironmentName;
  14. WebRoot = HostingUtilities.GetWebRoot(appEnvironment.ApplicationBasePath);
  15. WebRootFileSystem = new PhysicalFileSystem(WebRoot);
  16. foreach (var configure in configures)
  17. {
  18. configure.Configure(this);
  19. }
  20. }
  21. public string EnvironmentName { get; set; }
  22. public string WebRoot { get; private set; }
  23. public IFileSystem WebRootFileSystem { get; set; }
  24. }
  25. }

通过源代码我们知道有一个默认的“Development”

我们如何设定这个EnvironmentName?

stackoverflow上面的回答:

how-to-set-ihostingenvironment-environmentname-in-vnext-application

这里使用了直接设定的方法(以下代码段并非针对 .NETCore RC2)

  1. public Startup(IHostingEnvironment env)
  2. {
  3. // Setup configuration sources.
  4. Configuration = new Configuration()
  5. .AddJsonFile("config.json").AddEnvironmentVariables();
  6. Configuration.Set("ASPNET_ENV","Your own value");
  7. }

估计也可以写在Config的文件中。

  1. <configuration>
  2. <system.webServer>
  3. <handlers>
  4. <add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
  5. </handlers>
  6. <httpPlatform processPath="..\approot\web.cmd" arguments="--ASPNET_ENV Development" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600"></httpPlatform>
  7. </system.webServer>
  8. </configuration>

当然如果你去看最新版的代码,这里的环境变量关键字变成了 “ASPNETCORE_ENVIRONMENT”

(Hosting:Environment 和 ASPNET_ENV 都是旧的关键字了)

  1. /// <summary>
  2. /// Initializes a new instance of the <see cref="WebHostBuilder"/> class.
  3. /// </summary>
  4. public WebHostBuilder()
  5. {
  6. _hostingEnvironment = new HostingEnvironment();
  7. _configureServicesDelegates = new List<Action<IServiceCollection>>();
  8. _configureLoggingDelegates = new List<Action<ILoggerFactory>>();
  9. // This may end up storing null, but that's indistinguishable from not adding it.
  10. UseSetting(WebHostDefaults.EnvironmentKey, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
  11. // Legacy keys, never remove these.
  12. ?? Environment.GetEnvironmentVariable("Hosting:Environment")
  13. ?? Environment.GetEnvironmentVariable("ASPNET_ENV"));
  14. if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
  15. {
  16. Console.WriteLine("The environment variable 'Hosting:Environment' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
  17. }
  18. if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
  19. {
  20. Console.WriteLine("The environment variable 'ASPNET_ENV' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
  21. }
  22. }

总结

  1. 为了统一结构和启动机制,ASP.NET Core程序也是一种Console程序。
  2. 配置文件多样化,JSON,XML,INI格式文件都是被支持的
  3. IIS还是需要Webconfig文件的
  4. 整个程序的入口不是RC1的StartUp了。

    本文已经同步到ASP.Net Core MVC6 RC2 启动过程分析

    ASP.NET从MVC5升级到MVC6 总目录

ASP.Net Core MVC6 RC2 启动过程分析[偏源码分析]的更多相关文章

  1. Net Core MVC6 RC2 启动过程分析

    入口程序 如果做过Web之外开发的人,应该记得这个是标准的Console或者Winform的入口.为什么会这样呢?.NET Web Development and Tools Blog ASP.NET ...

  2. Flink的Job启动TaskManager端(源码分析)

    前面说到了  Flink的JobManager启动(源码分析)  启动了TaskManager 然后  Flink的Job启动JobManager端(源码分析)  说到JobManager会将转化得到 ...

  3. asp.net core结合docker实现自动化获取源码、部署、更新

    之前入坑dotnet core,由于一开始就遇到在windows上编译发布的web无法直接放到centos上执行.之后便直接研究docker,实现在容器中编译发布.然后就越玩越大,后来利用git的ho ...

  4. Asp.Net Core AuthorizeAttribute 和AuthorizeFilter 跟进及源码解读

    一.前言 IdentityServer4已经分享了一些应用实战的文章,从架构到授权中心的落地应用,也伴随着对IdentityServer4掌握了一些使用规则,但是很多原理性东西还是一知半解,故我这里持 ...

  5. spring mvc 启动过程及源码分析

    由于公司开源框架选用的spring+spring mvc + mybatis.使用这些框架,网上都有现成的案例:需要那些配置文件.每种类型的配置文件的节点该如何书写等等.如果只是需要项目能够跑起来,只 ...

  6. Flink的Job启动JobManager端(源码分析)

    通过前面的文章了解到 Driver将用户代码转换成streamGraph再转换成Jobgraph后向Jobmanager端提交 JobManager启动以后会在Dispatcher.java起来RPC ...

  7. storm启动过程之源码分析

    TopologyMaster: 处理拓扑的一些基本信息和工作,比如更新心跳信息,拓扑指标信息更新等   NimbusServer: ** * * NimbusServer work flow: 1. ...

  8. Flink的Job启动Driver端(源码分析)

    整个Flink的Job启动是通过在Driver端通过用户的Envirement的execute()方法将用户的算子转化成StreamGraph,然后得到JobGraph通过远程RPC将这个JobGra ...

  9. Netty服务端启动过程相关源码分析

    1.Netty 是怎么创建服务端Channel的呢? 我们在使用ServerBootstrap.bind(端口)方法时,最终调用其父类AbstractBootstrap中的doBind方法,相关源码如 ...

随机推荐

  1. ABP理论学习之导航(Navigation)

    返回总目录 本篇目录 创建菜单 注册导航提供者 展示菜单 每一个web应用在页面之间都有一些要导航的菜单.ABP提供了公用的基础设施来创建菜单并将菜单展示给用户. 创建菜单 一个应用可能由不同的模块组 ...

  2. HTML5- Canvas入门(四)

    前几章我们学习了矩形.多边形.圆形.曲线等图形的绘制,今天来学习下更简单一些的文本绘制及其各种功能方法. 在canvas中我们可以通过 strokeText() 和 fillText() 来绘制描边文 ...

  3. Lesson 1 A private conversation

    Text Last week I went to the theatre. I had a very good seat. The play was very intersting. I did no ...

  4. iOS7的启动画面设置及asset catalogs简介

    如果上网搜索一下“iOS App图标设置”或者“iOS App启动画面设置”肯定能找到不少文章,但内容大多雷同,就是让你按照某种尺寸制作若干张png图片,再按照苹果的命名规范,加入到项目中去,一行代码 ...

  5. 开发OpenWrt路由器上LuCI的模块

    [题外话] 学校里最近改造了校园网,要求必须用iNode验证,万幸的是路由器能刷OpenWrt,并且OpenWrt上有好多iNode认证的开源项目,比如njit8021xclient(以下简称njit ...

  6. RTSP协议转换RTMP直播协议

    RTSP协议转换RTMP直播协议 RTSP协议也是广泛使用的直播/点播流媒体协议,最近实现了一个RTSP协议转换RTMP直播协议的程序,为的是可以接收远端设备或服务器的多路RTSP直播数据,实时转换为 ...

  7. 2013 duilib入门简明教程 -- 前言(1)

        关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述.下面进入正题:     不看广告看疗效! 已有众多知名公司采用duilib做为界面库,如华为网盘. ...

  8. KnockoutJS 3.X API 第六章 组件(1) 组件和自定义元素 - 概述

    Components (组件)是一个强大的,干净的方式组织您的UI代码,可重复使用的块. : -可以表示单独的控件/窗口小部件或应用程序的整个部分 -包含自己的视图,通常(但可选)自己的视图模型 -可 ...

  9. OpenWebGlobe-开源三维GIS初体验(附源码和演示)

    1.OpenWebGlobe简介 OpenWebGlobe是一个高性能的三维引擎.可应用于可视化仿真,游戏,三维GIS,虚拟现实等领域.它使用纯javascript编写,可以运行在任何支持HTML5. ...

  10. 深入学习jQuery的三种常见动画效果

    × 目录 [1]显隐效果 [2]高度变化 [3]淡入淡出 前面的话 动画效果是jQuery吸引人的地方.通过jQuery的动画方法,能够轻松地为网页添加视觉效果,给用户一种全新的体验.jQuery动画 ...