Autofac.Core.Registration.ComponentNotRegisteredException,失败:处理后台作业时发生异常

Autofac.Core.Registration.ComponentNotRegisteredException, FAILED: An exception occurred during processing of a background job

异常: 请求的服务 'Mach.CharterPad.Business.TripManager' 尚未注册。要避免此异常,请注册组件以提供服务,使用 IsRegistered() 检查服务注册,或使用 ResolveOptional() 方法解析可选依赖项。

Autofac.Core.Registration.ComponentNotRegisteredException: 请求的服务'Mach.CharterPad.Business.TripManager' 尚未注册。要避免此异常,请注册组件以提供服务,使用 IsRegistered() 检查服务注册,或使用 ResolveOptional() 方法解析可选依赖项。

at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Hangfire.AutofacJobActivator.AutofacScope.Resolve(Type type)
   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
   at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_0.<PerformJobWithFilters>b__0()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
   at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)
   at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
   at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)

Startup.cs

private void ConfigureAutofac(HttpConfiguration config, IAppBuilder app)
{
  var builder = new ContainerBuilder();
  var businessasm = BuildManager.GetReferencedAssemblies()
                                .Cast<Assembly>()
                                .Where(n => n.FullName.Contains("Business"))
                                .FirstOrDefault();

  builder.RegisterAssemblyTypes(businessasm)
  .Where(t => t.Name.EndsWith("Manager"))
  .AsImplementedInterfaces()
  .InstancePerRequest();

//Set the dependency resolver to be Autofac.
   var container = builder.Build();
   config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
   Hangfire.GlobalConfiguration.Configuration.UseAutofacActivator(container, 
   false);
   config.MessageHandlers.Insert(0, new ApiDelegatingHandler());
   app.UseAutofacMiddleware(container);
   app.UseAutofacWebApi(config)
}

MyController.cs

[Route("{Id}")]
public IHttpActionResult GetById(long Id)
   {
     var result = TripManager.GetById(Id);  // WORKS PERFECT

     var jobId = BackgroundJob.Enqueue(() => TripManager.GetById(Id)); // Always go to Retries in Hangfire

     return Ok(result != null ? new ApiResponse(true, "Trip has been found", result) : new ApiResponse(false, "No record found", result));
   }

不幸的是,这里没有太多内容可以继续 - 没有实际问题,没有解释已采取哪些步骤来解决问题,已经研究了哪些问题等。

I recommend checking out this post on what makes a good SO question. 这可以帮助您 - 通过解决一些问题并帮助更多人关注问题;它可以帮助其他人 - 通过缩小需要查看的内容或准确理解您要拍摄的内容。每个人都会因问题写得好而获胜,即使是可能遇到类似问题并正在寻求帮助的人也是如此。

鉴于有一些猜测可以弄清楚你在问什么,我认为问题是这样的:

I have [some sort of an ASP.NET app, likely Web API] running an OWIN pipeline. I also have background jobs running via Hangfire. I'm trying to share a container across the ASP.NET app and the Hangfire jobs, but I see an exception [at some point, but it's unclear when]. Why might this exception be occurring?

嗯,首先,异常消息告诉你很多:

The requested service 'Mach.CharterPad.Business.TripManager' has not been registered.

正在查看您的注册情况...

builder.RegisterAssemblyTypes(businessasm)
  .Where(t => t.Name.EndsWith("Manager"))
  .AsImplementedInterfaces()
  .InstancePerRequest();

我立即看到两个潜在的问题:

  • 您已经使用了 AsImplementedInterfaces,这意味着如果您有 public class TripManager : ITripManager,那么它将 注册为 ITripManager。如果您只注册了接口,则无法解析具体类型。您还必须注册 AsSelf
  • 您已指定 InstancePerRequest 并且后台任务没有请求。那是行不通的。如果您想在每个后台任务中使用一个新的,则必须注册为 InstancePerDependencyInstancePerLifetimeScope;或 SingleInstance 如果您想在 Web 应用程序和后台任务之间共享单例。

MyController.cs 中,我看不到 TripManager 是如何解决的。我不知道那是对 TripManager.GetById(id) 的静态引用还是 属性。没有构造函数,因此您无法判断它是使用 ITripManager 还是 TripManager 或什么。

但是,那里的注册问题可能会为您提供足够的信息来开始解决问题。如果没有,我可能会建议您提出一个包含更多详细信息的新问题,以便人们可以更好地为您提供帮助。