ASP.NET Core与RESTful API 开发实战
上QQ阅读APP看书,第一时间看更新

3.1.3 Startup类

IWebHostBuilder接口有多个扩展方法,其中有一个很重要的是UseStartup方法,它主要向应用程序提供用于配置启动的类,而指定的这个类应具有以下两个方法。

ConfigureServices:用于向ASP.NET Core的依赖注入容器添加服务。

Configure:用于添加中间件,配置请求管道。

这两个方法都会在运行时被调用,且在应用程序的整个生命周期内,只执行一次。其中ConfigureServices方法是可选的,而Configure方法则是必选的。在程序启动时,它会执行ConfigureServices方法(如果有),将指定的服务放入应用程序的依赖注入容器中,然后再执行Configure方法,向请求管道中添加中间件。以下是一个典型的Startup类:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        …
        services.AddMvc();
        services.AddScoped<INoteRepository, NoteRepository>();
        …
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, INoteRepository noteRepository)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }
        …
        app.UseMvc();            
        …
    }
}

ConfigureServices方法有一个IServiceCollection类型的参数,使用它能够将应用程序级别的服务注册到ASP.NET Core默认的依赖注入容器中。Configure方法默认包含一个IApplicationBuilder类型的参数,通过它可以添加一个或多个中间件,所有添加的中间件将会对传入的HTTP请求进行处理,并将处理后的结果返回为发起请求的客户端。

当在ConfigureServices方法中向依赖注入容器添加了服务后,在后面的Configure方法中就可以通过参数将需要的服务注入进来,如上面的Configure方法中INoteRepository类型的 参数。

在配置启动时,除了使用IWebHostBuilder的UseStartup方法引用Startup类外,还可以直接使用IWebHostBuilder的ConfigureService和Configure两个扩展方法以内联的方式分别实现Startup类中对应的两个方法,如下所示。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureServices(service =>
        {
            service.AddMvc();
            service.AddScoped<INoteRepository, NoteRepository>();
        })
        .Configure(app =>
        {
            var scope = app.ApplicationServices.CreateScope();
            var noteRepository = scope.ServiceProvider.GetRequiredService <INoteRepository> ();
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        });

相比使用Startup类,这种方式的不足之处在于,在Configure扩展方法中,无法自由地为其从容器中注入所需要的参数,因此还需要从依赖注入容器中手工获取所需要的服务。另外,多次调用ConfigureServices方法将会逐一添加每个方法,将其中的服务添加到容器中,而多次调用Configure方法则仅最后一次的调用有效。