我已经在我的 .NET Core Web 应用程序的 Startup 类中安装并配置了 Hangfire,如下所示(删除了大量非 Hangfire 代码):
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseHangfireServer();
//app.UseHangfireDashboard();
//RecurringJob.AddOrUpdate(() => DailyJob(), Cron.Daily);
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration);
services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IPrincipal>((sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User);
services.AddScoped<IScheduledTaskService, ScheduledTaskService>();
services.AddHangfire(x => x.UseSqlServerStorage(connectionString));
this.ApplicationContainer = getWebAppContainer(services);
return new AutofacServiceProvider(this.ApplicationContainer);
}
}
public interface IScheduledTaskService
{
void OverduePlasmidOrdersTask();
}
public class ScheduledTaskService : IScheduledTaskService
{
public void DailyJob()
{
var container = getJobContainer();
using (var scope = container.BeginLifetimeScope())
{
IScheduledTaskManager scheduledTaskManager = scope.Resolve<IScheduledTaskManager>();
scheduledTaskManager.ProcessDailyJob();
}
}
private IContainer getJobContainer()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new BusinessBindingsModule());
builder.RegisterModule(new DataAccessBindingsModule());
return builder.Build();
}
}
如您所见,我正在使用 Autofac 进行 DI。我已设置为每次执行 Hangfire 作业时注入(inject)一个新容器。
目前,我有 UseHangfireDashboard()
以及添加我的重复作业的调用已被注释掉,我在引用 IPrincipal
的行上收到以下错误:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
我知道 Hangfire 没有 HttpContext
。我不太确定为什么它甚至会为 Hangfire 线程触发那行代码。我最终需要为我的 IPrincipal 依赖项解析一个服务帐户。
如何解决 Hangfire 和 HttpContext 的问题?
最佳答案
The main problem I'm having now is when I add UseHangfireServer, I then need to resolve HttpContext too
在这里找到Using IoC containers
HttpContext
is not availableRequest information is not available during the instantiation of a target type. If you register your dependencies in a request scope (
InstancePerHttpRequest
in Autofac,InRequestScope
in Ninject and so on), an exception will be thrown during the job activation process.So, the entire dependency graph should be available. Either register additional services without using the request scope, or use separate instance of container if your IoC container does not support dependency registrations for multiple scopes.
解决 .net 核心中的作用域依赖项需要一个请求,该请求在启动期间注册和激活作业时不可用。因此,请确保您在启动期间激活所需的服务未使用作用域生命周期注册。
services.AddTransient<IScheduledTaskManager, ScheduledTaskManageImplementation>();
现在剩下的就是配置应用程序以将该服务与重复作业一起使用,
public class Startup {
public IContainer ApplicationContainer { get; private set; }
public Startup(IHostingEnvironment env) {
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void Configuration(IApplicationBuilder app) {
// app.AddLogger...
//add hangfire features
app.UseHangfireServer();
app.UseHangfireDashboard();
//Add the recurring job
RecurringJob.AddOrUpdate<IScheduledTaskManager>(task => task.ProcessDailyJob(), Cron.Daily);
//app.UseMvc...
//...other code
}
public IServiceProvider ConfigureServices(IServiceCollection services) {
// Adding custom services
services.AddTransient<IScheduledTaskManager, ScheduledTaskManageImplementation>();
//add other dependencies...
// add hangfire services
services.AddHangfire(x => x.UseSqlServerStorage("<connection string>"));
//configure Autofac
this.ApplicationContainer = getWebAppContainer(services);
//get service provider
return new AutofacServiceProvider(this.ApplicationContainer);
}
IContainer getWebAppContainer(IServiceCollection service) {
var builder = new ContainerBuilder();
builder.RegisterModule(new BusinessBindingsModule());
builder.RegisterModule(new DataAccessBindingsModule());
builder.Populate(services);
return builder.Build();
}
//...other code
}
引用资料
关于c# - 解决 .NET Core 启动中的 Hangfire 依赖项/HttpContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44054578/