【问题标题】:Autofac OwnedInstances and ASP.NET Web API's InstancePerApiRequest supportAutofac OwnedInstances 和 ASP.NET Web API 的 InstancePerApiRequest 支持
【发布时间】:2013-06-20 14:58:31
【问题描述】:

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

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&lt;Owned&lt;ConfContext&gt;&gt;,我想获得单独的实例,但我得到的是相同的实例。如果我删除 InstancePerApiRequest 注册,在我只想按原样检索 ConfContext 的情况下,我将失去 Per API 请求支持。

这里有什么方法可以同时支持这两种情况吗?

编辑

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

【问题讨论】:

    标签: dependency-injection asp.net-web-api inversion-of-control ioc-container autofac


    【解决方案1】:

    在 Autofac 3.0 中,我添加了对将多个标签应用于生命周期范围的支持。您可以使用它为 API 请求和拥有的实例生命周期范围应用标签。

    Web API 生命周期范围的标记通过 AutofacWebApiDependencyResolver.ApiRequestTag 属性公开,Owned&lt;T&gt; 生命周期范围标记有它们的入口点 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 2013-06-24
      • 2012-06-20
      • 2012-09-13
      • 2014-07-19
      相关资源
      最近更新 更多