我已经在我的 Global.asax.cs 中注册了这样一个组件:
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>();
WebWorkContext
类:
public class WebWorkContext : IWorkContext
{
// Left out other code
}
IWorkContext
接口(interface):
public interface IWorkContext
{
// Left out other code
}
我得到的错误是:
No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
我如何让它工作?我想要这样的原因是因为工作环境处理诸如获取当前客户等事情。
还有一些问题。一次注册每个人是否明智/最佳做法?我是否需要在其他阶段添加更多组件?
最佳答案
用 InstancePerHttpRequest
标记的注册应该从每个 HTTP 请求期间创建和处理的特定嵌套生命周期范围中解析。
如果您将 IWorkContext
作为构造函数参数添加到您的 Controller 之一,您会发现注入(inject)了一个实例。在您的代码中,您试图从根生命周期范围而不是嵌套的“每个请求”生命周期范围解析您的服务。
如果您想在不运行您的应用程序的情况下测试解析服务,您将需要创建一个生命周期范围,其标签与在 HTTP 请求期间创建的标签相同。在 MVC 3 集成中,生命周期范围被标记为“httpRequest”。
using (var httpRequestScope = container.BeginLifetimeScope("httpRequest"))
{
Assert.That(httpRequestScope.Resolve<IWorkContext>(), Is.Not.Null);
}
我想我会更新 MVC 集成以通过 API 公开公开“httpRequest”标记名称,这样字符串值就不需要硬编码了。也可以将您自己的 ILifetimeScopeProvider
实现传递给 AutofacDependencyResolver
,这样您就可以在 ASP.NET 运行时之外控制生命周期范围的创建。当没有可用的 HTTP 请求时,这在单元测试中很有用。
关于c# - 如何解决 Autofac InstancePerHttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10027330/