.NET Core 实战 [No.330~332] Startup
在上一篇博客中的默认 ASP.NET Core Web 项目代码中都有看到一个 Startup
类,通过 UseStartup 方法指定该类。
csharp
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.Run();
Startup 并未要求类名为 Startup ,可以自定义类名,但要求类必须包含约定的方法:
ConfigureServices
这个方法是可选的,当需要向容器添加服务时才定义。
csharppublic void ConfigureServices(IServiceCollection services) { services.AddScoped<ConcreteServiceA>(); }
Configure
**此方法是必需的,它支持参数的依赖注入,**要求必需包含
IApplicationBuilder
类型的参数。如果有其它参数存在,IApplicationBuilder
类型的参数要放在参数列表的第一位,其余参数将由依赖注入来赋值。csharppublic void Configure(IApplicationBuilder app, IHostingEnvironment env, ConcreteServiceA a) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); a.Run(); }
除了使用约定方法来创建定义 Startup 类之外,还可以通过实现 IStartup
接口来定义 Startup 类。IStartup
接口定义如下:
csharp
public interface IStartup
{
void Configure(IApplicationBuilder app);
IServiceProvider ConfigureServices(IServiceCollection services);
}
下面是一个实现 IStartup
接口的示例。
csharp
public class MyStartup : IStartup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
return services.AddScoped<ConcreteA>()
.BuildServiceProvider();
}
}
另外,框架还提供了一个抽象类 StartupBase
,这个类已经实现了 IStartup
接口。
csharp
public class MyStartup : StartupBase
{
public override void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
由于这两种 Startup 类的实现并非约定,不能在 Configure 方法上接受依赖注入的对象,但可以通过构造函数参数来注入。
csharp
IHostingEnvironment _hostEnv;
public MyStartup(IHostingEnvironment env)
{
_hostEnv = env;
}
但是若要接受在 ConfigureServices 方法中注册的依赖注入对象则无法实现。
定义 Startup 类只是为了配置应用程序时更方便,实际启动时可以不使用 Startup 类。
csharp
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddScoped<ConcreteServiceA>();
})
.Configure(app =>
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
});
参考:《.NET Core 实战:手把手教你掌握 380 个精彩案例》 -- 周家安 著