在Application_start中注册RequestContext(global.asax)

时间:2012-06-08 08:28:25

标签: asp.net-mvc inversion-of-control autofac

我正在尝试为我的IoC容器(autofac)注册RequestContext。我在Application_start中进行了所有注册。

RequestContext注册如下所示:

builder.Register(x => HttpContext.Current.Request.RequestContext).As<RequestContext>();

这在dev webserver上工作正常,但在IIS 7(集成模式)中,问题是Application_start中没有RequestContext上下文。

我可以在这做什么?

1 个答案:

答案 0 :(得分:5)

这里有两个问题需要解决:

  1. 如何注册RequestContext?
  2. 为什么RequestContext没有正确解析?
  3. 如果您正在使用Autofac MVC集成,那么您最容易注册的是:

    builder.RegisterModule<AutofacWebTypesModule>();
    

    已经有一个模块可以注册各种Web抽象(HttpContextBase,RequestContext等),这些抽象适当地限定为每个HTTP请求实例。经过测试,可以为您节省大量时间。

    相反,如果您想自己手动注册它,那么如果将其范围限定为InstancePerHttpRequest,则执行您所拥有的操作(这样您就无法在每个请求上反复使用它)。

    此外,您可以将其“链接”到当前上下文中,如模块中所示:

    builder.Register(c => new HttpContextWrapper(HttpContext.Current))
        .As<HttpContextBase>()
        .InstancePerHttpRequest();
    builder.Register(c => c.Resolve<HttpRequestBase>().RequestContext)
        .As<RequestContext>()
        .InstancePerHttpRequest();
    

    这照顾第一部分,但第二部分有点棘手。

    如果您在应用启动时遇到错误,因为RequestContext不可用,那么您应用中的某个地方,您尝试在实际请求之前解析使用RequestContext的内容。 For例如,一个HttpModule实现,它手动尝试解析具有RequestContext作为构造函数参数的东西。

    注册中的lambda实际上直到解析后才会被评估,所以错误可能来自你正在解决的过早尝试使用RequestContext的东西。

    在这种情况下,问题是:当您尝试解析RequestContext并且没有请求时,您希望如何处理解决方案?

    默认情况下,您会收到异常,这可能就是您现在所看到的。

    如果您希望它为null,请执行以下注册:

    // Register context as instance-per-dependency and handle the
    // case where it's null. Also handle HttpException because IIS7
    // can throw if you access HttpContext.Current too soon in app startup.
    builder.Register(
      c => {
        try
        {
          var ctx = HttpContext.Current;
          return ctx == null ? null : new HttpContextWrapper(ctx);
        }
        catch(HttpException)
        {
          return null;
        }
      }).As<HttpContextBase>();
    
    // RequestContext also gets registered instance-per-dependency
    // and handles the null context case.
    builder.Register(
      c => {
        var ctx = c.Resolve<HttpRequestBase>();
        return ctx == null ? null : ctx.RequestContext;
      }).As<RequestContext>();
    

    这应该让你超越应用启动问题。

    所有这些...... 您应该弄清楚在应用程序启动时尝试使用RequestContext的内容,看看您是否可以修复设计。在正常情况下,你不应该最终需要这样做。