2

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

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

编辑

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

4

1 回答 1

4

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

Web API 生命周期范围的标记通过该AutofacWebApiDependencyResolver.ApiRequestTag属性公开,Owned<T>生命周期范围用它们的 entry point 标记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

于 2013-06-21T12:38:43.677 回答