2

对于我的ASP.NET Web API项目,我有以下设置它使用Autofac作为IoC容器:Autofac OwnedInstances和ASP.NET Web API的支持InstancePerApiRequest

protected void Application_Start(object sender, EventArgs e) 
{ 
    HttpConfiguration config = GlobalConfiguration.Configuration; 

    config.DependencyResolver = 
     new AutofacWebApiDependencyResolver(
      RegisterServices(new ContainerBuilder())); 

    config.Routes.MapHttpRoute("DefaultRoute", "api/{controller}"); 
} 

private static IContainer RegisterServices(ContainerBuilder builder) 
{ 
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 
    builder.RegisterType<ConfContext>().InstancePerApiRequest(); 

    return builder.Build(); 
} 

和我有下面的消息处理以检索ConfContext实例只是为了好玩:

public class MyHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     ConfContext ctx = (ConfContext)request.GetDependencyScope().GetService(typeof(ConfContext)); 
     return base.SendAsync(request, cancellationToken); 
    } 
} 

由于构造控制器之前,我的消息处理程序将被调用,我应该在控制器获得相同ConfContext实例。但是,如果我尝试检索ConfContext作为Func<Owned<ConfContext>>,但我想获得相同的实例,我想获取单独的实例。如果我删除了InstancePerApiRequest注册,那么我将丢失Per API请求支持,因为我只想按原样检索ConfContext

有什么办法可以在这里支持这两种情况吗?

编辑

示例应用程序是在这里:https://github.com/tugberkugurlu/EntityFrameworkSamples/tree/master/EFConcurrentAsyncSample/EFConcurrentAsyncSample.Api

回答

4

在Autofac 3.0我添加了应用多个标签一辈子范围的支持。您可以使用它来为API请求和拥有的实例生存期范围应用标记。

Web API生命周期范围的标记通过AutofacWebApiDependencyResolver.ApiRequestTag属性公开,并且Owned<T>生命周期范围标记为其入口点new TypedService(typeof(T))

把它们放在一个方便的注册扩展方法中,你会得到下面的代码。

public static class RegistrationExtensions 
{ 
    public static IRegistrationBuilder<TLimit, TActivatorData, TStyle> 
     InstancePerApiRequestOrOwned<TLimit, TActivatorData, TStyle>(
      this IRegistrationBuilder<TLimit, TActivatorData, TStyle> registration) 
    { 
     if (registration == null) throw new ArgumentNullException("registration"); 

     var tags = new object[] {AutofacWebApiDependencyResolver.ApiRequestTag, new TypedService(typeof(TLimit))}; 

     return registration.InstancePerMatchingLifetimeScope(tags); 
    } 
} 

现在你可以在注册你的类型时使用扩展方法,一切都很好。

builder.RegisterType<ConfContext>().InstancePerApiRequestOrOwned(); 

我向您发送了一个展示此代码的请求。

https://github.com/tugberkugurlu/EntityFrameworkSamples/pull/1