2

Для моего ASP.NET Web API проекта, у меня есть следующие настройки, которые используют Autofac как контейнер IoC:Autofac OwnedInstances и ASP.NET Web API в

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, я потеряю поддержку API Per API в случаях, когда я хочу просто получить ConfContext, как есть.

Есть ли способ поддержать оба случая здесь?

Редактировать

Пример приложения здесь: https://github.com/tugberkugurlu/EntityFrameworkSamples/tree/master/EFConcurrentAsyncSample/EFConcurrentAsyncSample.Api

ответ

4

В Autofac 3.0 я добавил поддержку для применения нескольких меток к пожизненной области. Вы можете использовать это, чтобы применять теги для запросов API и областей использования экземпляра Owned экземпляра.

Тег для охвата жизненного цикла веб-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

Смежные вопросы