anjoy8 / Blog.Core

💖 ASP.NET Core 8.0 全家桶教程,前后端分离后端接口,vue教程姊妹篇,官方文档:
http://apk.neters.club/.doc
Apache License 2.0
5.06k stars 1.38k forks source link

应用启动时对初始化服务的改进 #329

Closed HuiJiOnGit closed 1 year ago

HuiJiOnGit commented 1 year ago

Program中有如下配置中间件的代码

var scope = app.Services.GetRequiredService<IServiceScopeFactory>().CreateScope();
var myContext = scope.ServiceProvider.GetRequiredService<MyContext>();
var tasksQzServices = scope.ServiceProvider.GetRequiredService<ITasksQzServices>();
var schedulerCenter = scope.ServiceProvider.GetRequiredService<ISchedulerCenter>();
var lifetime = scope.ServiceProvider.GetRequiredService<IHostApplicationLifetime>();
app.UseSeedDataMiddle(myContext, builder.Environment.WebRootPath);
app.UseQuartzJobMiddleware(tasksQzServices, schedulerCenter);
app.UseConsulMiddle(builder.Configuration, lifetime);
app.ConfigureEventBus();

我认为可以一些改进, 理由如下:

  1. UseSeedDataMiddle, UseQuartzJobMiddleware这几个并不符合中间件的定义, 中间件应该是有关键的RequestDelegate来对请求管道进行next或短路.
  2. 以上几个服务都是做某件事,启动一些服务,并不会插手请求处理过程, 并不需要写在配置写在传统的Configure配置中间件的地方
  3. 有些启动服务使用了异步方法, 但是扩展方法本身并不是异步的, 比如UseSeedDataMiddle这个方法中同步调用了DBSeed.SeedAsync(myContext, webRootPath).Wait();UseQuartzJobMiddleware中的schedulerCenter.AddScheduleJobAsync(item).Result;

综上我认为可以使用 IHostedServiceBackgroundService 来对应用启动时执行操作和启动对应服务

好处:

  1. Asp.Net Core自带, 不需要引入第三方组件
  2. IHostedService可以有效针对需要在应用启动时进行操作的需求, 应用会在执行完ConfigureServicesConfigure后, 在host启动前执行, 符合现有逻辑启动操作的时机
  3. 支持异步操作和完整的DI注入

需要改进的有

anjoy8 commented 1 year ago

你好,感谢提出改进意见,确实是 这几个中间件,确实并不涉及到管道相关的概念,只是在启动的时候,把响应的服务启动。 我一直用IHostedService来实现定时任务,当然如果不用Timer,就可以了。

你也可以帮忙先写一个pr,感觉你的提议很好,只要响应的参数都能获取到的话。