如何在ASP.NET MVC 4中使用Autofac注入HttpContextBase?

21

我正在使用 ASP.MVC 4Autofac

我在我的 global.asax.cs 文件中注册了以下内容:

ContainerBuilder builder = new ContainerBuilder();

builder.Register(c => c.Resolve<HttpContextBase>().Request)
     .As<HttpRequestBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Response)
     .As<HttpResponseBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
     .As<HttpServerUtilityBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
     .As<HttpSessionStateBase>()
     .InstancePerHttpRequest();

builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerHttpRequest();

在我的主页控制器中,我有以下代码(仅用于测试):

private readonly HttpContextBase httpContext;

public HomeController(HttpContextBase httpContext)
{
     this.httpContext = httpContext;
}

我曾经在一个ASP.NET MVC 3项目中使用了完全相同的代码,并且它正常工作。但是在这个项目中,我却遇到了错误。我不确定为什么会出错?我得到的错误信息是:

'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'无法找到'MyProject.Web.Controllers.HomeController'类型的任何构造函数可以使用可用的服务和参数进行调用:无法解析构造函数'Void .ctor(System.Web.HttpContextBase)'的参数'System.Web.HttpContextBase httpContext'。在Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable<code>1 parameters)、Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable<code>1 parameters)、Autofac.Core.Resolving.InstanceLookup.Execute()、Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable<code>1 parameters)以及Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable<code>1 parameters)方法中发生异常。在另一个我想要注入HttpContextBase的项目中,我也遇到了同样的错误。

我不太确定为什么会出现这种情况?难道我需要在ASP.NET 4中进行不同的操作吗?


3
在你的代码中,我看不到你注册HttpContextBase本身的地方...尝试使用builder.RegisterModule(new AutofacWebTypesModule());注册AutofacWebTypesModule - nemesv
是的,我刚刚在他们的网站上看到了这个。我是否应该先注册AutofacWebTypesModule,然后再注册builder.Register(c => c.Resolve<HttpContextBase>().Request)..? - Brendan Vogt
在这种情况下,注册顺序不应该有影响。 - nemesv
1个回答

34
感谢nemesv
我最终进行了更换:
builder.Register(c => c.Resolve<HttpContextBase>().Request)
     .As<HttpRequestBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Response)
     .As<HttpResponseBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
     .As<HttpServerUtilityBase>()
     .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
     .As<HttpSessionStateBase>()
     .InstancePerHttpRequest();

只需使用以下内容:

builder.RegisterModule(new AutofacWebTypesModule());

现在它可以工作了。 不确定有什么区别,但是模块中的代码看起来与我上面的代码完全相同。


19
如果您检查AutofacWebTypesModule的源代码,您可以看到您漏掉了最重要的一行 builder.Register(c => new HttpContextWrapper(HttpContext.Current)) .As<HttpContextBase>() .InstancePerHttpRequest();,它注册了HttpContextBase - nemesv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接