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