我的项目结构与:
相同https://github.com/MarlabsInc/webapi-angularjs-spa
我已按照以下说明操作:
http://docs.hangfire.io/en/latest/background-methods/using-ioc-containers.html
所以我创建了一个容器作业激活器。
在我的Bootstrapper.cs
中containerBuilder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().AsImplementedInterfaces().InstancePerApiRequest();
containerBuilder.RegisterType<UnitOfWork>().As<IUnitOfWork>().AsImplementedInterfaces().InstancePerApiRequest();
containerBuilder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());
IContainer container = containerBuilder.Build();
Hangfire.GlobalConfiguration.Configuration
.UseAutofacActivator(container);
JobActivator.Current = new AutofacJobActivator(container);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
我的启动类有一个方法:
GlobalConfiguration.Configuration
.UseSqlServerStorage("entitiesDB",
new SqlServerStorageOptions
{
PrepareSchemaIfNecessary = false,
InvisibilityTimeout = TimeSpan.FromMinutes(30)
});
app.UseHangfireDashboard();
app.UseHangfireServer();
在控制器中:我正在尝试将2000发票的状态更新为&#34;已批准&#34; 所以这个方法很简单如下:
foreach(int id in invoiceIds)
{
BackgroundJob.Enqueue<IInvoiceService>(a => a.UpdateInvoice(id));
}
现在我在SQL中查询:
select * from HangFire.[State]
我在数据列中收到以下异常:
{&#34; FailedAt&#34;:&#34; 2015-07-07T10:00:40.9454943Z&#34;&#34; ExceptionType&#34;:&#34; Autofac.Core.DependencyResolutionException&# 34;,&#34; ExceptionMessage&#34;:&#34;否 带有标记匹配的范围&#39; AutofacWebRequest&#39;是可见的 请求实例的范围。这通常表明 正在请求按照HTTP请求注册的组件 一个SingleInstance()组件(或类似的场景。)在网络下 集成始终请求来自的依赖项 DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime, 从来没有从容器 。本身&#34;&#34; ExceptionDetails&#34;:&#34; Autofac.Core.DependencyResolutionException: 没有标记匹配的范围&#39; AutofacWebRequest&#39;是可见的 请求实例的范围。这通常表明 正在请求按照HTTP请求注册的组件 一个SingleInstance()组件(或类似的场景。)在网络下 集成始终请求来自的依赖项 DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime, 从来没有从容器本身。\ r \ n at Autofac.Core.Lifetime.MatchingScopeLifetime.FindScope(ISharingLifetimeScope mostNestedVisibleScope)\ r \ n at Autofac.Core.Resolving.InstanceLookup..ctor(IComponentRegistration 注册,IResolveOperation上下文,ISharingLifetimeScope mostNestedVisibleScope,IEnumerable
1 parameters)\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1个参数)\ r \ n at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration 注册,IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable
1个参数)\ r \ n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration 注册,IEnumerable1 parameters)\r\n at Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable
1个参数)\ r \ n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context,Service service,IEnumerable1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable
1个参数)\ r \ n at Autofac.ResolutionExtensions.Resolve(IComponentContext context,Type serviceType,IEnumerable`1参数)\ r \ n at Autofac.ResolutionExtensions.Resolve(IComponentContext context,Type service.)\ r \ n在Hangfire.AutofacJobActivator.ActivateJob(类型 jobType)\ r \ n在Hangfire.Common.Job.Activate(JobActivator 活化剂)&#34;}
有人可以帮我理解我做错了吗?
答案 0 :(得分:2)
您正在使用InstancePerApiRequest
,因此您的IoC容器知道为每个API请求创建新实例。
但是,您的后台作业未在API请求中执行,因此您的IoC容器不知道如何解决您的依赖项。
HttpContext不可用
在实例化目标类型期间,请求信息不可用。如果在请求范围中注册依赖项(Autofac中的InstancePerHttpRequest,Ninject中的InRequestScope等),则在作业激活过程中将抛出异常。
因此,整个依赖图应该可用。在不使用请求范围的情况下注册其他服务,或者如果您的IoC容器不支持多个范围的依赖注册,则使用单独的容器实例。
根据this related SO question,Autofac不支持注册多个范围,因此您需要:
<强>更新强>:
Hangfire Autofac integration package引入了InstancePerBackgroundJob()
扩展方法,并建议Autofac支持注册多个范围,如下所示:
builder.RegisterType<Database>()
.InstancePerBackgroundJob()
.InstancePerHttpRequest();
但是,它仅适用于Hangfire.Autofac的1.2.0-beta1版本,该版本需要使用Hangfire 1.5.0-beta1。