我正在使用HangFire定期向后台用户发送电子邮件。
我正在从数据库中获取电子邮件地址,但不确定是否要将数据库上下文“注入”到负责正确发送电子邮件的服务中
这正常工作,有更好的方法吗?
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Context context)
{
(...)
app.UseHangfireDashboard();
app.UseHangfireServer(new BackgroundJobServerOptions
{
HeartbeatInterval = new System.TimeSpan(0, 0, 5),
ServerCheckInterval = new System.TimeSpan(0, 0, 5),
SchedulePollingInterval = new System.TimeSpan(0, 0, 5)
});
RecurringJob.AddOrUpdate(() => new MessageService(context).Send(), Cron.Daily);
(...)
app.UseMvc();
}
public class MessageService
{
private Context ctx;
public MessageService(Context c)
{
ctx = c;
}
public void Send()
{
var emails = ctx.Users.Select(x => x.Email).ToList();
foreach (var email in emails)
{
sendEmail(email, "sample body");
}
}
}
答案 0 :(得分:1)
答案 1 :(得分:0)
对于您的问题,绝对需要使用DI(StructureMap等)。请重构您的配置文件,并从配置类中解耦“上下文”类依赖项。还介绍了一个容器类来映射DI类(自动或手动)。
将容器添加到Hangfire:
GlobalConfiguration.Configuration.UseStructureMapActivator(Bootstrapper.Bootstrap());
还可以在配置类中更改作业注册:
RecurringJob.AddOrUpdate<MessageService>(x => x.Send(), Cron.Daily);
答案 2 :(得分:0)
我只是看了类似的问题,却找不到一个地方的信息,所以在这里发布我的解决方案。
假设您将Context
配置为服务,即
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
....
services.AddDbContext<Context>(options => { ... });
....
}
这使IServiceProvider
能够解决Context
依赖性。
接下来,我们需要更新MessageService
类,以使其不再永久保存Context
,而仅将其实例化以执行任务。
public class MessageService
{
IServiceProvider _serviceProvider;
public MessageService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Send()
{
using (IServiceScope scope = _serviceProvider.CreateScope())
using (Context ctx = scope.ServiceProvider.GetRequiredService<Context>())
{
var emails = ctx.Users.Select(x => x.Email).ToList();
foreach (var email in emails)
{
sendEmail(email, "sample body");
}
}
}
}
最后,我们要求 Hangfire 为我们实例化MessageService
,它也将为我们解决IServiceProvider
的依赖性:
RecurringJob.AddOrUpdate<MessageService>(x => x.Send(), Cron.Daily);