asp.net core Series Startup

This article simply record ASP.NET Core, some use the startup class.

 I. Introduction

In Startup class, there are two general methods:

  • ConfigureServices method: application to configure the service. 
  • Configure: Create the request processing pipeline applications

They are when the application starts, the ASP.NET Core runtime call:

public class Startup
{
    // Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    }

    // Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        ...
    }
}

 

When applied when the host is Built (established), Startup class is assigned to the application.

In the Program, when Build on the host builder is invoked, the host application is built.

The Startup class is specified by the calling WebHostBuilderExtensions.UseStartup <TStartup> method.

public  class Program 
{ 
    public  static  void the Main ( String [] args) 
    { 
        CreateWebHostBuilder (args). Build () .Run (); // when the method is called Build, host application is established, while the application is assigned to the Startup 
    } 

    public  static IWebHostBuilder CreateWebHostBuilder ( String [] args) => 
        WebHost.CreateDefaultBuilder (args) 
            .UseStartup <the Startup> (); 
}

 

In the startup class, a dependency injection common usage:

public  class Startup 
{ 
    private  readonly IHostingEnvironment _env;
    private  readonly IConfiguration _config;
    private  readonly ILoggerFactory _loggerFactory; 

    public Startup (IHostingEnvironment env, IConfiguration config, 
        ILoggerFactory loggerFactory ) 
    { 
        _env = env; 
        _config = config; 
        _loggerFactory = loggerFactory; 
    } 

    Public  void ConfigureServices (IServiceCollection services) 
    { 
        var logger = _loggerFactory.CreateLogger<Startup>();

        if (_env.IsDevelopment())
        {
            // Development service configuration

            logger.LogInformation("Development environment");
        }
        else
        {
            // Non-development service configuration
            logger.LogInformation($"Environment: {_env.EnvironmentName}");
        }

        // Configuration is available during startup.
        // Examples:
        //   _config["key"]
        //   _config["subsection:suboption1"]
    }
}

Injection IHostingEnvironment, when the Startup (e.g., StartupDevelopment etc.) defined in a different environment, at runtime, select the appropriate Startup. 

Two .ConfigureServices method

It has three characteristics:

  • Optional 
  • In the call to invoke before the Configure method ConfigureServices
  • Configuration options as agreed to set

1. Typically a call Add {Service} and services.Configure {Service}. For example: the Configure the Identity Services .

 

2. host might before the Startup method is called, configure some services. For example:  at The Host .

 

Before startup is called, CreateDefaultBuilder method of configuring a host.

3. Add {Service} is IServiceCollection extension method, following are some use:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    // Add application services. 添加应用的服务
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

添加 services 到 service container 使它们在应用和Configure方法中可用。services方法可以通过 dependency injection 或 ApplicationServices 解析。

三.The Configure method

Configure方法用来指定应用怎样 处理HTTP request。请求管道(request pipeline)通过添加中间组件到IApplicationBuilder实例中来配置。

ASP.NET Core 模板 配置的管道:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}

使用Use扩展方法添加一个或多个中间组件到请求管道。例如,UseMvc扩展方法添加 Routing Middleware 到请求管道 并且配置MVC 作为一个默认的处理器。

四.Convenience methods

不使用Startup类配置services和request processing pipeline。在host builder 上调用ConfigureServices和Configure的简便方法。如果存在多个ConfigureServices的调用,会依次添加。如果存在多个Configure方法的调用,最后一个Configure的调用会被使用。

public class Program
{
    public static IHostingEnvironment HostingEnvironment { get; set; }
    public static IConfiguration Configuration { get; set; }

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
            })
            .ConfigureServices(services =>
            {
                ...
            })
            .Configure(app =>
            {
                var loggerFactory = app.ApplicationServices
                    .GetRequiredService<ILoggerFactory>();
                var logger = loggerFactory.CreateLogger<Program>();
                var env = app.ApplicationServices.GetRequiredServices<IHostingEnvironment>();
                var config = app.ApplicationServices.GetRequiredServices<IConfiguration>();

                logger.LogInformation("Logged in Configure");

                if (env.IsDevelopment())
                {
                    ...
                }
                else
                {
                    ...
                }

                var configValue = config["subsection:suboption1"];

                ...
            });
}

五.Extend Startup with startup filters (使用startup filter扩展 Startup)

使用 IStartupFilter ,在应用的Configure 中间件管道的开头或末尾配置中间件

IStartupFilter 实现Configure方法,它会接收和返回一个Action<IApplicationBuilder>。而IApplicationBuilder定义了一个类来配置一个应用的请求管道。

这些filters会按照添加到services container的顺序被调用。

下面是一个例子:

RequestSetOptionsMiddleware

public class RequestSetOptionsMiddleware
{
    private readonly RequestDelegate _next;
    private IOptions<AppOptions> _injectedOptions;

    public RequestSetOptionsMiddleware(
        RequestDelegate next, IOptions<AppOptions> injectedOptions)
    {
        _next = next;
        _injectedOptions = injectedOptions;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        Console.WriteLine("RequestSetOptionsMiddleware.Invoke");

        var option = httpContext.Request.Query["option"]; //取请求中的option参数

        if (!string.IsNullOrWhiteSpace(option))
        {
            _injectedOptions.Value.Option = WebUtility.HtmlEncode(option);
        }

        await _next(httpContext);
    }
}

RequestSetOptionsMiddleware 中间件被配置在 RequestSetOptionsStartupFilter 类中:

public class RequestSetOptionsStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return builder =>
        {
            builder.UseMiddleware<RequestSetOptionsMiddleware>();
            next(builder);
        };
    }
}

IStartupFilter 在 ConfigureServices中被注册到 service container, 并且从Startup类的外部增强Startup:

WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddTransient<IStartupFilter, 
            RequestSetOptionsStartupFilter>();
    })
    .UseStartup<Startup>()
    .Build();

当option的查询字符串存在时,中间件会在MVC中间件之前处理这个值

中间件的执行顺序是按照IStartupFilter的注册顺序

六. 补充

这里晚上补充下 ApplicationServices 解析services的使用

参考网址:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.2

Guess you like

Origin www.cnblogs.com/Vincent-yuan/p/11105523.html