C# 如何解决Autofac InstancePerHttpRequest
我已经在我的Global.asax.cs中注册了这样的组件:C# 如何解决Autofac InstancePerHttpRequest,c#,asp.net-mvc-3,dependency-injection,autofac,C#,Asp.net Mvc 3,Dependency Injection,Autofac,我已经在我的Global.asax.cs中注册了这样的组件: ContainerBuilder builder = new ContainerBuilder(); builder.RegisterControllers(Assembly.GetExecutingAssembly()); builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerHttpRequest(); IContain
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerHttpRequest();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// This is where my error happens, not sure why?
var workContext = container.Resolve<IWorkContext>();
IWorkContext
界面:
public interface IWorkContext
{
// Left out other code
}
我得到的错误是:
从请求实例的作用域中看不到标记与“httpRequest”匹配的作用域。这通常表示在web集成下,SingleInstance()组件(或类似场景)请求根据HTTP请求注册的组件始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,而不是从容器本身
我怎样才能让它工作?我之所以希望如此,是因为工作上下文处理诸如获取当前客户等事情
还有一些问题。一次注册每一个项目是否明智/最佳做法?我是否需要在另一个阶段添加更多组件?标记为
InstancePerHttpRequest
的注册预计将从每个HTTP请求期间创建和处理的特定嵌套生存期范围中解决
如果将IWorkContext
作为构造函数参数添加到一个控制器中,您将发现注入了一个实例。在代码中,您试图从根生存期范围而不是嵌套的“每个请求”生存期范围解析服务
如果您想在不运行应用程序的情况下测试解析服务,则需要使用与HTTP请求期间创建的标记相同的标记创建生存期范围。在MVC3集成中,生命周期范围被标记为“httpRequest”
使用(var-httpRequestScope=container.BeginLifetimeScope(“httpRequest”))
{
Assert.That(httpRequestScope.Resolve(),Is.Not.Null);
}
我想我会更新MVC集成,通过API公开“httpRequest”标记名,这样就不需要硬编码字符串值。还可以将自己的
ILifetimeScopeProvider
实现传递给AutofacDependencyResolver
,以便您可以在ASP.NET运行时之外控制生存期作用域的创建。当没有HTTP请求可用时,这在单元测试中很有用。我在WebForms中这样做:
this.RoutingService = ((Global)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve<RoutingService>();
this.RoutingService=((全局)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve();
您想在哪里解决问题?我只是在玩玩,所以这是在应用程序启动方法中构建容器之后直接完成的。我不知道如何在我的应用程序中的其他位置获取容器?是的,请将RequestLifetimeScopeProvider中的HttpRequestTag设置为公共。然后,我们不需要硬编码标记值。
using (var httpRequestScope = container.BeginLifetimeScope("httpRequest"))
{
Assert.That(httpRequestScope.Resolve<IWorkContext>(), Is.Not.Null);
}
this.RoutingService = ((Global)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve<RoutingService>();