如何解决 Autofac InstancePerHttpRequest [英] How to resolve Autofac InstancePerHttpRequest

查看:53
本文介绍了如何解决 Autofac InstancePerHttpRequest的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的 Global.asax.cs 中注册了一个这样的组件:

I have registered a component like this in my 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 接口:

public interface IWorkContext
{
     // Left out other code
}

我得到的错误是:

从请求实例的范围中看不到具有与httpRequest"匹配的标签的范围.这通常表明作为每个 HTTP 请求注册的组件正在被 SingleInstance() 组件(或类似场景)请求.在 Web 集成下,始终从 DependencyResolver.Current 或 ILifetimeScopeProvider.RequestLifetime 请求依赖项,而不是从容器本身请求依赖项.

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.

我如何让它发挥作用?我之所以想要这种方式,是因为工作上下文处理诸如获取当前客户之类的事情.

How do I get this to work? This reason why I want it this way is because the work context handles stuff like getting the current customer etc.

还有一些问题.一次注册是否明智/最佳做法?是否会出现我需要在另一个阶段添加更多组件的情况?

Some more questions. Is it wise/best practices to register every at once? Will the be scenarios that I will need to add more components at another stage?

推荐答案

使用 InstancePerHttpRequest 标记的注册应从在每个 HTTP 请求期间创建和处置的特定嵌套生命周期范围解析.

Registrations that are marked with InstancePerHttpRequest are expected to be resolved from a particular nested lifetime scope that is created and disposed during each HTTP request.

如果您将 IWorkContext 作为构造函数参数添加到您的控制器之一,您会发现注入了一个实例.在您的代码中,您试图从根生命周期范围而不是嵌套的每个请求"生命周期范围解析您的服务.

If you add IWorkContext as a constructor parameter to one of your controllers you will find that an instance is injected. In your code you are attempting to resolve your service from the root lifetime scope and not the nested "per request" lifetime scope.

如果您想在不运行您的应用程序的情况下测试解析服务,您将需要创建一个生命周期作用域,其标记与 HTTP 请求期间创建的标记相同.在 MVC 3 集成中,生命周期范围被标记为httpRequest".

If you want to test resolving the service without running up your application you will need to create a lifetime scope with the same tag as the one created during the HTTP request. In the MVC 3 integration the lifetime scope is tagged "httpRequest".

using (var httpRequestScope = container.BeginLifetimeScope("httpRequest"))
{
    Assert.That(httpRequestScope.Resolve<IWorkContext>(), Is.Not.Null);
}

我想我将更新 MVC 集成以通过 API 公开公开httpRequest"标记名称,这样字符串值就不需要硬编码了.还可以将您自己的 ILifetimeScopeProvider 实现传递给 AutofacDependencyResolver,以便您可以在 ASP.NET 运行时之外控制生命周期范围的创建.当没有可用的 HTTP 请求时,这在单元测试中很有用.

I think I will update the MVC integration to expose the "httpRequest" tag name publicly through the API so that string values don't need to be hard coded. It is also possible to pass your own ILifetimeScopeProvider implementation to the AutofacDependencyResolver so that you can control the creation of lifetime scopes outside of the ASP.NET runtime. This is useful in unit tests when there is no HTTP request available.

这篇关于如何解决 Autofac InstancePerHttpRequest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆