Startup
类
Startup
类是 ASP.NET Core
应用程序启动默认调用的类,该类是在 Program.cs
中配置:
urion.Web.Entry\Program.cs using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; namespace Furion.Web.Entry { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder .Inject() .UseStartup<Startup>(); }); } } }
Startup
两个重要方法
Startup
默认有两个重要的方法:
ConfigureServices
:配置应用所需服务,在该方法中可以添加应用所需要的功能或服务Configure
:配置应用请求处理管道
默认代码如下:
Furion.Web.Entry\Startup.cs using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; namespace Furion.Web.Entry { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
在这里,不打算详细讲 Startup
类的具体功能和作用。
AppStartup
在 Furion
框架中,提供了更为灵活的 Startup
类配置方式,无需在 Web 启用层
中配置,可将配置放到任何项目层。
可能会有读者有疑问,为什么要多此一举呢?原因有几点:
Startup
类默认和Web 应用层
绑定在一起,这样就会导致如果我创建了新的Web 应用层
,Startup
又要重新配置- 随着业务的增长,需要集成越来越多的第三方服务,这时候
Startup
类就会变得越来越臃肿,难以维护 Startup
类无法与其他项目类型进行共用
所以,Furion
提供了更加灵活的配置方式:AppStartup
。
如何配置 AppStartup
AppStartup
是一个抽象的空类,没有任何定义成员。正是因为这样,才提供更加灵活的配置方式。
AppStartup
约定
AppStartup
派生类只有两个小约定:
- 任何公开、非静态、返回值为
void
且方法第一个参数是IServiceCollection
类型,那么他就是一个ConfigureServices
方法 - 任何公开、非静态、返回值为
void
且方法第一个参数是IApplicationBuilder
类型,第二个参数是IWebHostEnvironment
类型,那么他就是一个Configure
方法
所以,我们可以自由的编写方法,只要遵循约定即可,如:
using Microsoft.Extensions.DependencyInjection; namespace Furion.EntityFramework.Core { public class MyStartup : AppStartup { public void ConfigureServices(IServiceCollection services) { services.AddDataValidation(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseSwagger(); } // 可以随意定义名字和方法 public void XXXXName(IServiceCollection services) { } // 可以随意定义名字和方法 public void ZZZName(IApplicationBuilder app, IWebHostEnvironment env) { } } }
默认情况下,AppStartup
配置顺序由所在程序集的名称进行正序调用,如果我们需要配置执行顺序,只需要在 AppStartup
派生类中贴 [AppStartup(order)]
特性即可。
order
数值越大,越在前面调用,如:
using Microsoft.Extensions.DependencyInjection; namespace Furion.EntityFramework.Core { [AppStartup(10)] public class FirstStartup : AppStartup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
using Microsoft.Extensions.DependencyInjection; namespace Furion.EntityFramework.Core { [AppStartup(9)] public class SecondStartup : AppStartup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
FirstStartup
会在 SecondStartup
之前调用。
AppStartup
方法调用顺序
AppStartup
方法调用顺序和方法的书写先后有关,越在前面的方法越先调用。
Startup
配置最佳实践
建议 Web
启动层的 Startup.cs
保持为空方法体,如:
Furion.Web.Entry\Startup.cs using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; namespace Furion.Web.Entry { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
将所有 Web 应用层
配置迁移到 Furion.Web.Core.Startup.cs
中,如:
Furion.Web.Core\Startup.cs using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Furion.Web.Core { [AppStartup(800)] public sealed class FurWebCoreStartup : AppStartup { public void ConfigureServices(IServiceCollection services) { services.AddCorsAccessor(); services.AddControllers().AddInject(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseCorsAccessor(); app.UseAuthentication(); app.UseAuthorization(); app.UseInject(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
这样,后续更换 Web 应用层
也无需重新配置 Startup.cs
关于 appsettings.json
在默认情况下,ASP.NET Core
配置放在 appsettings.json
中配置,但是这样的方式和 Startup.cs
配置一样的道理,一旦我们更换了 Web 应用层
,那么 appsettings.json
又要重新配置一次。
所以,Furion
框架提供了更加灵活的方式配置 appsettings.json
,只需要在任何项目层根目录下创建 .json
文件即可。Furion
框架最后会自动合并所有分散的配置文件。
如我们在 Furion.EntityFramework.Core
层创建 dbsettings.json
配置数据库连接字符串,如:
Furion.EntityFramework.Core\dbsettings.json { "ConnectionStrings": { "DbConnectionString": "Server=localhost;Database=Furion;User=sa;Password=000000;MultipleActiveResultSets=True;", "Sqlite3ConnectionString": "Data Source=./Furion.db" } }
无需在 appsettings.json
中配置,下面是 appsettings.json
默认代码:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information", "Microsoft.EntityFrameworkCore": "Information" } }, "AllowedHosts": "*" }
这样我们把配置文件分散在不同项目层之后,就可以实现共用和共享了。
神奇的 Inject()
Furion.Web.Entry\Program.cs using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; namespace Furion.Web.Entry { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.Inject() .UseStartup<Startup>(); }); } } }
Furion.Web.Entry\Startup.cs using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; namespace Furion.Web.Entry { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { } } }
非常简单吧。我们后续创建任何 MVC
,RazorPages
,Blazor
项目只需要添加 Furion.Web.Core
引用和调用 Inject()
即可。