我正在尝试解决在单个Container中使用多个生命周期的问题。
问题与InstancePerRequest()
的实施有关。
有一个基于WebAPI且带有自定义WebHandler的应用程序,因此Autofac无法定义LifetimeScope
是初始化还是处置。所以我不能使用基本的InstancePerRequest()
。我决定根据Autofac documentation
InstancePerRequest()
Autofac注册如下:
...
private static IContainer Container;
private static void RegisterServices()
{
var builder = new ContainerBuilder();
builder.Register((c, p) => new CustomClass(p.Named<List<int>>("codes"), p.Named<User>("user")))
.InstancePerRequest();
Container = builder.Build();
}
public static ILifetimeScope BeginLifetimeScope()
{
return Container.BeginLifetimeScope(new[] { MatchingScopeLifetimeTags.RequestLifetimeScopeTag });
}
...
根据{{3}}(第2点),MatchingScopeLifetimeTags.RequestLifetimeScopeTag
是Autofac Custom每个请求语义中必需的
所以我手动创建了LifetimeScope
:
... // AutofacHelper.BeginLifetimeScope() is implemented above
using (var lifetimeScope = AutofacHelper.BeginLifetimeScope())
{
result = InvokeRequest(request.Api, context);
}
...
问题是LifetimeScope
的数量与请求的数量一样多。我需要的范围从远离代码的地方开始,在那儿我需要访问它。我需要可以从任何地方访问当前范围。
我想我必须用LifetimeScope
标记每个HttpContext.Current
,这将足以定义我需要使用的范围。
但是我该怎么做?使用参数BeginLifetimeScope()
实现new[] { MatchingScopeLifetimeTags.RequestLifetimeScopeTag, HttpContext.Current }
会导致异常,因为找不到所需的作用域。
是否可以定义当前请求中使用的范围?例如使用我的自定义唯一标签? ILifetimeScope
仅对父范围实现。有没有没有实现子范围的原因,以便我可以根据HttpContext.Current
来使用它们?
有什么想法吗?
谢谢!
答案 0 :(得分:1)
我认为您拥有的实际上是完全正确的。
问题是LifetimeScope的数量与请求的数量一样
这不是问题,这就是它的工作方式。即使是现在进入ASP.NET Core,也不仅仅是Autofac -每个请求的实例意味着每个请求有一个生存期范围。
您有两个选项可以跟踪生存期范围。
首先,您可以将ILifetimeScope
注入到任何构造函数中,注入的对象是拥有该对象的生命周期范围。因此,如果您已经注册了InstancePerRequest
,那么您只需添加一个ILifetimeScope
构造函数参数即可,它可以获取请求范围。
第二,创建时,您始终可以将生存期范围存储在HttpContext.Current
中。
using (var lifetimeScope = AutofacHelper.BeginLifetimeScope())
{
HttpContext.Current.Items["RequestLifetimeScope"] = lifetimeScope;
result = InvokeRequest(request.Api, context);
}
然后,如果您绝对必须获得该范围(例如服务位置),则可以从当前上下文进行操作。
var scope = (ILifetimeScope)HttpContext.Current.Items["RequestLifetimeScope"];
var x = scope.Resolve<IService>();
如果您想要更多有关范围的存储位置,访问方式的指针...,或者甚至要使用某些内置的帮助程序,我都将签出the source for the Autofac WebAPI integration。您可能还想了解Web API本身如何移动请求范围-它stores the scope along with the inbound request message,因此您可以调用message.GetDependencyScope()
并获取当前的生存期范围。您可以做类似的事情。
如果您使用的是OWIN管道,那么OWIN integration for WebAPI, too可能会给您一些有关如何连接事物的想法。