理解ASP.NET Core 启动类(Startup)

目录
  • 准备工作:一份ASP.NET Core Web API应用程序
  • Startup类
    • Startup构造函数
    • ConfigureServices
    • Configure
  • 省略Startup类
  • IStartupFilter
  • IHostingStartup
    • HostingStartup 程序集
    • HostingStartup 特性
    • 激活HostingStarup程序集
      • 1.使用环境变量(推荐)
      • 2.在程序中配置
  • 多环境配置
    • 环境配置方式
    • 基于环境的 Startup
      • 1.将IWebHostEnvironment注入 Startup 类
      • 2.Startup 方法约定
      • 3.Startup 类约定

准备工作:一份ASP.NET Core Web API应用程序

当我们来到一个陌生的环境,第一件事就是找到厕所在哪。

当我们接触一份新框架时,第一件事就是找到程序入口,即Main方法

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

代码很简单,典型的建造者模式:通过IHostBuilder创建一个通用主机(Generic Host),然后启动它(至于什么是通用主机,咱们后续的文章会说到)。咱们不要一上来就去研究CreateDefaultBuilderConfigureWebHostDefaults这些方法的源代码,应该去寻找能看的见、摸得着的,很明显,只有Startup

Startup类

Startup类承担应用的启动任务,所以按照约定,起名为Startup,不过你可以修改为任意类名(强烈建议类名为Startup)。

默认的Startup结构很简单,包含:

  • 构造函数
  • Configuration属性
  • ConfigureServices方法
  • Configure方法
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // 该方法由运行时调用,使用该方法向DI容器添加服务
    public void ConfigureServices(IServiceCollection services)
    {
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    // 该方法由运行时调用,使用该方法配置HTTP请求管道
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    }
}

Startup构造函数

当使用通用主机(Generic Host)时,Startup构造函数支持注入以下三种服务类型:

  • IConfiguration
  • IWebHostEnvironment
  • IHostEnvironment
public Startup(
    IConfiguration configuration,
    IHostEnvironment hostEnvironment,
    IWebHostEnvironment webHostEnvironment)
{
    Configuration = configuration;
    HostEnvironment = hostEnvironment;
    WebHostEnvironment = webHostEnvironment;
}

public IConfiguration Configuration { get; }

public IHostEnvironment HostEnvironment { get; set; }

public IWebHostEnvironment WebHostEnvironment { get; set; }

这里你会发现 HostEnvironmentWebHostEnvironment 的实例是同一个。别着急,后续文章我们聊到Host的时候,你就明白了。

ConfigureServices

  • 该方法是可选的
  • 该方法用于添加服务到DI容器中
  • 该方法在Configure方法之前被调用
  • 该方法要么无参数,要么只能有一个参数且类型必须为IServiceCollection
  • 该方法内的代码大多是形如Add{Service}的扩展方法

常用的服务有(部分服务框架已默认注册):

  • AddControllers:注册Controller相关服务,内部调用了AddMvcCoreAddApiExplorerAddAuthorizationAddCorsAddDataAnnotationsAddFormatterMappings等多个扩展方法
  • AddOptions:注册Options相关服务,如IOptions<>IOptionsSnapshot<>IOptionsMonitor<>IOptionsFactory<>IOptionsMonitorCache<>等。很多服务都需要Options,所以很多服务注册的扩展方法会在内部调用AddOptions
  • AddRouting:注册路由相关服务,如IInlineConstraintResolverLinkGeneratorIConfigureOptions<RouteOptions>RoutePatternTransformer
  • AddAddLogging:注册Logging相关服务,如ILoggerFactoryILogger<>IConfigureOptions<LoggerFilterOptions>>
  • AddAuthentication:注册身份认证相关服务,以方便后续注册JwtBearer、Cookie等服务
  • AddAuthorization:注册用户授权相关服务
  • AddMvc:注册Mvc相关服务,比如Controllers、Views、RazorPages等
  • AddHealthChecks:注册健康检查相关服务,如HealthCheckServiceIHostedService

Configure

  • 该方法是必须的
  • 该方法用于配置HTTP请求管道,通过向管道添加中间件,应用不同的响应方式。
  • 该方法在ConfigureServices方法之后被调用
  • 该方法中的参数可以接受任何已注入到DI容器中的服务
  • 该方法内的代码大多是形如Use{Middleware}的扩展方法
  • 该方法内中间件的注册顺序与代码的书写顺序是一致的,先注册的先执行,后注册的后执行

常用的中间件有

  • UseDeveloperExceptionPage:当发生异常时,展示开发人员异常信息页。如图

  • UseRouting:路由中间件,根据Url中的路径导航到对应的Endpoint。必须与UseEndpoints搭配使用。
  • UseEndpoints:执行路由所选择的Endpoint对应的委托。
  • UseAuthentication:身份认证中间件,用于对请求用户的身份进行认证。比如,早晨上班打卡时,管理员认出你是公司员工,那么才允许你进入公司。
  • UseAuthorization:用户授权中间件,用于对请求用户进行授权。比如,虽然你是公司员工,但是你是一名.NET开发工程师,那么你只允许坐在.NET开发工程师区域的工位上,而不能坐在老总的办公室里。
  • UseMvc:Mvc中间件。
  • UseHealthChecks:健康检查中间件。
  • UseMiddleware:用来添加匿名中间件的,通过该方法,可以方便的添加自定义中间件。

省略Startup类

另外,Startup类也可以省略,直接进行如下配置即可(虽然可以这样做,但是不推荐):

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // ConfigureServices 可以调用多次,最终会将结果聚合
            webBuilder.ConfigureServices(services =>
            {
            })
            // Configure 如果调用多次,则只有最后一次生效
            .Configure(app =>
            {
                var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
            });
        });

IStartupFilter

public interface IStartupFilter
{
    Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next);
}

有时,我们想要将一系列相关中间件的注册封装到一起,那么我们只需要通过实现IStartupFilter,并在Startup.ConfigureServices中配置IStartupFilter的依赖注入即可。

  • IStartupFilter中配置的中间件,总是比Startup类中Configure方法中的中间件先注册;对于多个IStartupFilter实现,执行顺序与服务注册时的顺序一致

我们可以通过一个例子来验证一下中间件的注册顺序。

首先是三个IStartupFilter的实现类:

public class FirstStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    => app =>
    {
        app.Use((context, next) =>
        {
            Console.WriteLine("First");
            return next();
        });
        next(app);
    };
}

public class SecondStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    => app =>
    {
        app.Use((context, next) =>
        {
            Console.WriteLine("Second");
            return next();
        });
        next(app);
    };
}

public class ThirdStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    => app =>
    {
        app.Use((context, next) =>
        {
            Console.WriteLine("Third");
            return next();
        });
        next(app);
    };
}

接下来进行注册:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices(services =>
        {
            // 第一个被注册
            services.AddTransient<IStartupFilter, FirstStartupFilter>();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .ConfigureServices(services =>
        {
            // 第三个被注册
            services.AddTransient<IStartupFilter, ThirdStartupFilter>();
        });

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 第二个被注册
        services.AddTransient<IStartupFilter, SecondStartupFilter>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // 第四个被注册
        app.Use((context, next) =>
        {
            Console.WriteLine("Forth");
            return next();
        });
    }
}

最后通过输出可以看到,执行顺序的确是这样子的。

First
Second
Third
Forth

IHostingStartup

IStartupFilter不同的是,IHostingStartup可以在启动时通过外部程序集向应用增加更多功能。不过这要求必须调用ConfigureWebHostConfigureWebHostDefaults等类似用来配置Web主机的扩展方法

我们经常使用的Nuget包SkyApm.Agent.AspNetCore就使用了该特性。

下面我们就来看一下该如何使用它。

HostingStartup 程序集

要创建HostingStartup程序集,可以通过创建类库项目或无入口点的控制台应用来实现。

接下来咱们还是看一下上面提到过的SkyApm.Agent.AspNetCore

using SkyApm.Agent.AspNetCore;

[assembly: HostingStartup(typeof(SkyApmHostingStartup))]

namespace SkyApm.Agent.AspNetCore
{
    internal class SkyApmHostingStartup : IHostingStartup
    {
        public void Configure(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
        }
    }
}

该HostingStartup类:

  • 实现了IHostingStartup接口
  • Configure方法中使用IWebHostBuilder来添加增强功能
  • 配置了HostingStartup特性

HostingStartup 特性

HostingStartup特性用于标识哪个类是HostingStartup类,HostingStartup类需要实现IHostingStartup接口。

当程序启动时,会自动扫描入口程序集和配置的待激活的的程序集列表(参见下方:激活HostingStarup程序集),来找到所有的HostingStartup特性,并通过反射的方式创建Startup并调用Configure方法。

SkyApm.Agent.AspNetCore为例

using SkyApm.Agent.AspNetCore;

[assembly: HostingStartup(typeof(SkyApmHostingStartup))]

namespace SkyApm.Agent.AspNetCore
{
    internal class SkyApmHostingStartup : IHostingStartup
    {
        public void Configure(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
        }
    }
}

激活HostingStarup程序集

要激活HostingStarup程序集,我们有两种配置方式:

1.使用环境变量(推荐)

使用环境变量,无需侵入程序代码,所以我更推荐大家使用这种方式。

配置环境变量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES,多个程序集使用分号(;)进行分隔,用于添加要激活的程序集。变量WebHostDefaults.HostingStartupAssembliesKey就是指代这个环境变量的Key。

另外,还有一个环境变量,叫做ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES,多个程序集使用分号(;)进行分隔,用于排除要激活的程序集。变量WebHostDefaults.HostingStartupExcludeAssembliesKey就是指代这个环境变量的Key。

我们在 launchSettings.json 中添加两个程序集:

"environmentVariables": {
    "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore;HostingStartupLibrary"
}

2.在程序中配置

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseSetting(
                WebHostDefaults.HostingStartupAssembliesKey,
                "SkyAPM.Agent.AspNetCore;HostingStartupLibrary")
            .UseStartup<Startup>();
        });

这样就配置完成了,很🐮🍺的一个功能点吧!

需要注意的是,无论使用哪种配置方式,当存在多个HostingStartup程序集时,将按配置这些程序集时的书写顺序执行 Configure方法。

多环境配置

一款软件,一般要经过需求分析、设计编码,单元测试、集成测试以及系统测试等一系列测试流程,验收,最终上线。那么,就至少需要4套环境来保证系统运行:

  • Development:开发环境,用于开发人员在本地对应用进行调试运行
  • Test:测试环境,用于测试人员对应用进行测试
  • Staging:预发布环境,用于在正式上线之前,对应用进行集成、测试和预览,或用于验收
  • Production:生产环境,应用的正式线上环境

环境配置方式

通过环境变量ASPNETCORE_ENVIRONMENT指定运行环境

注意:如果未指定环境,默认情况下,为 Production

在项目的Properties文件夹里面,有一个“launchSettings.json”文件,该文件是用于配置VS中项目启动的。
接下来我们就在launchSettings.json中配置一下。
先解释一下该文件中出现的几个参数:

  • commandName:指定要启动的Web服务器,有三个可选值:

Project:启动 Kestrel

IISExpress:启动IIS Express

IIS:不启用任何Web服务器,使用IIS

  • dotnetRunMessages:bool字符串,指示当使用 dotnet run 命令时,终端能够及时响应并输出消息,具体参考stackoverflowgithub issue
  • launchBrowser:bool值,指示当程序启动后,是否打开浏览器
  • launchUrl:默认启动路径
  • applicationUrl:应用程序Url列表,多个URL之间使用分号(;)进行分隔。当launchBrowser为true时,将{applicationUrl}/{launchUrl}作为浏览器默认访问的Url
  • environmentVariables:环境变量集合,在该集合内配置环境变量
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    // 如果不指定profile,则默认选择第一个
    // Development
    "ASP.NET.WebAPI": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    // Test
    "ASP.NET.WebAPI.Test": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Test"
      }
    },
    // Staging
    "ASP.NET.WebAPI.Staging": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    },
    // Production
    "ASP.NET.WebAPI.Production": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    },
    // 用于测试在未指定环境时,默认是否为Production
    "ASP.NET.WebAPI.Default": {
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5000"
    }
  }
}

配置完成后,就可以在VS上方工具栏中的项目启动处选择启动项了

基于环境的 Startup

Startup类支持针对不同环境进行个性化配置,有三种方式:

  • 1.将IWebHostEnvironment注入 Startup 类
  • 2.Startup 方法约定
  • 3.Startup 类约定

1.将IWebHostEnvironment注入 Startup 类

通过将IWebHostEnvironment注入 Startup 类,然后在方法中使用条件判断书写不同环境下的代码。该方式适用于多环境下,代码差异较少的情况。

public class Startup
{
    public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public IConfiguration Configuration { get; }

    public IWebHostEnvironment WebHostEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        if (WebHostEnvironment.IsDevelopment())
        {
            Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsTest())
        {
            Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsStaging())
        {
            Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsProduction())
        {
            Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
        }
    }

    public void Configure(IApplicationBuilder app)
    {
        if (WebHostEnvironment.IsDevelopment())
        {
            Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsTest())
        {
            Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsStaging())
        {
            Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
        }
        else if (WebHostEnvironment.IsProduction())
        {
            Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
        }
    }
}

public static class AppHostEnvironmentEnvExtensions
{
    public static bool IsTest(this IHostEnvironment hostEnvironment)
    {
        if (hostEnvironment == null)
        {
            throw new ArgumentNullException(nameof(hostEnvironment));
        }

        return hostEnvironment.IsEnvironment(AppEnvironments.Test);
    }
}

public static class AppEnvironments
{
    public static readonly string Test = nameof(Test);
}

2.Startup 方法约定

上面的方式把不同环境的代码放在了同一个方法中,看起来比较混乱也不容易区分。因此我们希望ConfigureServicesConfigure能够根据不同的环境进行代码拆分。

我们可以通过方法命名约定来解决,约定Configure{EnvironmentName}ServicesConfigure{EnvironmentName}Services来装载不同环境的代码。如果当前环境没有对应的方法,则使用原来的ConfigureServicesConfigure方法。

我就只拿 Development 和 Production 举例了

public class Startup
{
    // 我这里注入 IWebHostEnvironment,仅仅是为了打印出来当前环境信息
    public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public IConfiguration Configuration { get; }

    public IWebHostEnvironment WebHostEnvironment { get; }

    #region ConfigureServices
    private void StartupConfigureServices(IServiceCollection services)
    {
        Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
    }

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    public void ConfigureProductionServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        StartupConfigureServices(services);
    }
    #endregion

    #region Configure
    private void StartupConfigure(IApplicationBuilder app)
    {
        Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
    }

    public void ConfigureDevelopment(IApplicationBuilder app)
    {
        StartupConfigure(app);
    }

    public void ConfigureProduction(IApplicationBuilder app)
    {
        StartupConfigure(app);
    }

    public void Configure(IApplicationBuilder app)
    {
        StartupConfigure(app);
    }
    #endregion
}

3.Startup 类约定

该方式适用于多环境下,代码差异较大的情况。

程序启动时,会优先寻找当前环境命名符合Startup{EnvironmentName}的 Startup 类,如果找不到,则使用名称为Startup的类

首先,CreateHostBuilder方法需要做一处修改

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            //webBuilder.UseStartup<Startup>();

            webBuilder.UseStartup(typeof(Startup).GetTypeInfo().Assembly.FullName);
        });

接下来,就是为各个环境定义 Startup 类了(我就只拿 Development 和 Production 举例了)

public class StartupDevelopment
{
    // 我这里注入 IWebHostEnvironment,仅仅是为了打印出来当前环境信息
    public StartupDevelopment(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public IConfiguration Configuration { get; }

    public IWebHostEnvironment WebHostEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
    }

    public void Configure(IApplicationBuilder app)
    {
        Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
    }
}

public class StartupProduction
{
    public StartupProduction(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
    {
        Configuration = configuration;
        WebHostEnvironment = webHostEnvironment;
    }

    public IConfiguration Configuration { get; }

    public IWebHostEnvironment WebHostEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
    }

    public void Configure(IApplicationBuilder app)
    {
        Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
    }
}

到此这篇关于理解ASP.NET Core 启动类(Startup)的文章就介绍到这了,更多相关ASP.NET Core Startup内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 深入探究ASP.NET Core Startup初始化问题

    前言 Startup类相信大家都比较熟悉,在我们使用ASP.NET Core开发过程中经常用到的类,我们通常使用它进行IOC服务注册,配置中间件信息等.虽然它不是必须的,但是将这些操作统一在Startup中做处理,会在实际开发中带来许多方便.当我们谈起Startup类的时候你有没有好奇过以下几点 为何我们自定义的Startup可以正常工作. 我们定义的Startup类中ConfigureServices和Configure只能叫这个名字才能被调用到吗? 在使用泛型主机(IHostBuilder)

  • 理解ASP.NET Core 中间件(Middleware)

    目录 中间件 中间件管道 Run Use UseWhen Map MapWhen Run & Use & UseWhen & Map & Map 编写中间件并激活 基于约定的中间件 基于工厂的中间件 基于约定的中间件 VS 基于工厂的中间件 中间件 先借用微软官方文档的一张图: 可以看到,中间件实际上是一种配置在HTTP请求管道中,用来处理请求和响应的组件.它可以: 决定是否将请求传递到管道中的下一个中间件 可以在管道中的下一个中间件处理之前和之后进行操作 此外,中间件的注

  • ASP.NET Core使用HostingStartup增强启动操作方法详解

    概念 在ASP.NET Core中我们可以使用一种机制来增强启动时的操作,它就是HostingStartup.如何叫"增强"操作,相信了解过AOP概念的同学应该都非常的熟悉.我们常说AOP使用了关注点分离的方式,增强了对现有逻辑的操作.而我们今天要说的HostingStartup就是为了"增强"启动操作,这种"增强"的操作甚至可以对现有的程序可以做到无改动的操作.例如,外部程序集可通过HostingStartup实现为应用提供配置服务.注册服务或

  • 理解ASP.NET Core 启动类(Startup)

    目录 准备工作:一份ASP.NET Core Web API应用程序 Startup类 Startup构造函数 ConfigureServices Configure 省略Startup类 IStartupFilter IHostingStartup HostingStartup 程序集 HostingStartup 特性 激活HostingStarup程序集 1.使用环境变量(推荐) 2.在程序中配置 多环境配置 环境配置方式 基于环境的 Startup 1.将IWebHostEnvironm

  • ASP.NET Core基础之Startup类

    ASP.NET Core必须包含Startup类.它就像 Global.asax 文件,我们传统的 .NET 应用程序.如名称建议的那样,在应用程序启动时首先执行它.在程序类的Main方法中配置主机时,可以使用UseStartup()扩展方法配置启动类.请查看下面的程序类,并重点介绍 WebBuilder.UseStartup() 方法. 名称"Startup"是按照ASP.NET Core约定进行的. 但是,您可以给Startup类指定任何名称,只需在UseStartup ()方法中

  • 理解ASP.NET Core 依赖注入(Dependency Injection)

    目录 依赖注入 什么是依赖注入 依赖注入有什么好处 ASP.NET Core内置的依赖注入 服务生存周期 服务释放 TryAdd{Lifetime}扩展方法 解析同一服务的多个不同实现 Replace && Remove 扩展方法 Autofac 服务解析和注入 构造函数注入 方法注入 属性注入 一些注意事项 框架默认提供的服务 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接收注入的对象实例即可. 微软官方文档-DI 依赖注入有什么好处 依赖

  • 理解ASP.NET Core 错误处理机制(Handle Errors)

    目录 使用中间件进行错误处理 开发人员异常页 IDeveloperPageExceptionFilter 异常处理程序 通过lambda提供异常处理程序 异常处理程序页 无响应正文的Http错误状态码处理 UseStatusCodePages UseStatusCodePagesWithRedirects UseStatusCodePagesWithReExecute 使用过滤器进行错误处理 错误处理中间件 VS 异常过滤器 注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博

  • 基于 .NET 6 的ASP.NET Core启动地址配置方法及优先级顺序

    目录 前言: 一.设置方法 ​1.applicationUrl属性​ ​2.环境变量​ ​3.命令行参数​ ​4.UseUrls方法​ .NET5版本 .NET6版本 ​5.UseKestrel方法​ ​6.WebApplication.Urls.Add方法​ ​7.appsettings.json文件​ 二.优先级 三.结论 前言: 上次,我们讨论了如何通过配置或代码方式修改启动地址:<​ ​ASP.NET Core启动地址配置方法及优先级顺序​​>.不过是基于 .NET 5 版本的. 由于

  • ASP.NET Core启动地址配置方法及优先级顺序

    目录 一.设置方法 1.applicationUrl属性 2.环境变量 3.命令行参数 4.UseUrls方法 5.UseKestrel方法 二.优先级 结论: 默认情况下,ASP.NET Core使用下列2个启动地址: http://localhost:5000https://localhost:5001 同时,我们也可以通过配置或代码方式修改启动地址. 那么,这几种修改方式都是什么?谁最后起作用呢? 一.设置方法 1.applicationUrl属性 launchSettings.json文

  • 基于 .NET 6 的ASP.NET Core启动地址配置方法及优先级顺序

    目录 前言: 一.设置方法 ​1. applicationUrl 属性​ ​2.环境变量​ ​3.命令行参数​ ​4. UseUrls 方法​ .NET 5 版本 .NET 6 版本 ​5. UseKestrel 方法​ ​6. WebApplication.Urls.Add 方法​ ​7. appsettings.json 文件​ 二.优先级 三.结论 前言: 上次,我们讨论了如何通过配置或代码方式修改启动地址:<​​ASP.NET Core启动地址配置方法及优先级顺序​​>.不过是基于 .

  • asp.net core实体类生产CRUD后台管理界面

    目录 前言介绍 演示功能 机制设定 1.添加.修改数据 2.列表查询.过滤筛选 3.删除数据 思考人生 前言介绍 喜欢小规模团队的"单打独斗",有的时候即使在大公司,也经常做着3-5个人团队的小项目,相信很多人有类似的经历. 本文介绍如何将项目中已存在的[实体类],直接生产出 CRUD 后台管理界面. 对于通用后台管理系统的生成,除了单纯的对单表 crud 操作外,我还喜欢利用导航属性的操作,比如: 1.Song.Tag 多对多场景,添加/更新 Song 时可以把 Tag 一起保存: 2.列表页

  • ASP.NET Core应用启动Startup类简介

    1.前言 Core与早期版本的 ASP.NET 对比,配置应用程序的方式的 Global.asax.FilterConfig.cs和RouteConfig.cs 都被Program.cs 和 Startup.cs取代了.Program.cs作为Web应用程序的默认入口,在没有任何修改的情况下,会调用同目录下Startup.cs中的ConfigureServices 和 Configure方法. 2.Startup类 Startup类配置服务和应用的请求管道.Program.Main方法是应用程序

随机推荐