无法创建请求生存期范围,因为HttpContext不可用

时间:2012-06-14 20:11:28

标签: asp.net-mvc-3 autofac unit-of-work signalr

很难尝试使用某些异步非httprequest设置AutoFac。

我在App_Start上有以下内容

        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterType<sfEntities>().As<IUnitOfWork>().InstancePerHttpRequest();
        builder.RegisterGeneric(typeof(sfRepository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
        builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerHttpRequest();
        builder.RegisterType<EmailServices>().As<IEmailServices>().InstancePerHttpRequest();
        builder.RegisterType<UserServices>().As<IUserServices>().InstancePerHttpRequest();
        builder.RegisterType<ChatServices>().As<IChatServices>().InstancePerHttpRequest();
        builder.RegisterType<DefaultFormsAuthentication>();
        builder.RegisterType<WebSecurity>();
        builder.RegisterType<Chat>();
        IContainer container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

如果我改为InstancePerLifetimeScope(),我会遇到UnitofWork.SaveChanges()的问题。除了异步调用之外,以这种方式设置工作正常。

p.s。:UnitOfWork在服务之间传递EF DbContext,以确保使用相同的实例并正确处置。如果我改为InstancePerLifetimeScope,我在调用.SaveChanges()时会遇到身份冲突,可能是因为应该有多个UnitOfWork实例。

以下代码抛出以下异常:

Timer timer = new Timer(new TimerCallback(OnTimer), null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));

    private static void OnTimer(object o)
    {
         using (var timerScope = AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope())
         {
             var chatServices = timerScope.Resolve<IChatServices>();
             chatServices.MarkInactiveUsers();
         }
    }
  

从请求实例的作用域中看不到具有匹配'httpRequest'的标记的作用域。这通常表示注册为每HTTP请求的组件正被SingleInstance()组件(或类似场景)重新请求。在Web集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,从不从容器本身请求

在SignalR上,以下代码抛出以下异常:

SignalR.GlobalHost.DependencyResolver.Register(typeof(Chat), () => new Chat(DependencyResolver.Current.GetService<IUnitOfWork>(), DependencyResolver.Current.GetService<IChatServices>(), DependencyResolver.Current.GetService<IUserServices>()));
  

由于HttpContext不可用,因此无法创建请求生存期范围

提前致谢!

2 个答案:

答案 0 :(得分:3)

  

很难尝试使用某些异步非httprequest设置AutoFac。

对于非http请求,或者更具体地说,对于非ASP.NET管道请求(如WCF或ServiceStack),您绝对应该将所有InstancePerHttpRequest()代码更改为InstancePerLifetimeScope()。您可以而且应该这样做,因为InstancePerLifetimeScope() will make it resolvable in both ASP.NET pipeline and non-ASP.NET pipeline contexts

  

如果我改为InstancePerLifetimeScope(),我会遇到UnitofWork.SaveChanges()的问题。这种方式设置正常,除了异步调用...如果我改为InstancePerLifetimeScope我在调用.SaveChanges()时遇到了身份冲突,可能是因为应该有多个UnitOfWork实例。

是的,UnitOfWork应该有多个实例,但您可以通过一个应限定为InstancePerLifetimeScope()的注册来实现这一目标:

示例:

builder.RegisterType<NhUnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();

答案 1 :(得分:1)

IChatServices服务已注册为InstancePerHttpRequest,因此仅在http请求生命周期范围内可用。您正在从对当前请求没有“访问权限”的应用程序范围进行解析,因此会因您提及的错误而失败。所以,是的,要使计时器工作,您必须在应用程序范围内注册该服务。

基本上,您可以使用访问应用程序作用域服务的请求范围服务,但不是相反。

问题是:UnitOfWork.SaveChanges做什么以及你遇到了什么“问题”?请详细说明。