2015-02-25 3 views
4

У меня есть приложение WebApi с использованием OWIN и Autofac. Хотя контроллеры и параметры решаются правильно, я хотел бы иметь возможность использовать OwinContext.Get<type> для разрешения типов, зарегистрированных в Autofac. Это возможно?OWIN Разрешение обслуживания Использование Autofac

Уже установлено app.UseAutofacMiddleware(container); и config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

К примеру, я зарегистрировал builder.Register<IAppConfiguration>(c => new AppConfig()); и я хотел бы, чтобы решить его с помощью owinContext.Get<IAppConfiguration>().

ответ

4

IOwinContext.Get использует словарь Environment, разрешая объекты, зарегистрированные непосредственно с помощью Owin, он не учитывает контейнер Autofac.

Мне удалось это сделать, обратившись к Autofac OwinLifetimeScope в свойстве Environment и используя область действия для решения этой проблемы.

Вы можете получить доступ к LifetimeScope с помощью этого кода

var scope=OwinContext.Get<Autofac.Core.Lifetime.LifetimeScope>("autofac:OwinLifetimeScope"); 

и затем

scope.GetService(type) 

Вы должны проверить нулям и записать его в лучшую сторону, так как метод расширения может быть.

+0

Не работает, если ключ 'autofac: OwinLifetimeScope' имеет большое руководство позади него. Вместо этого используйте 'owinContext.GetAutofacLifetimeScope()'. –

+0

У моего ключа также есть направляющая за ним - знаете ли вы, почему? – aup

7

Существует нет способа получить OwinContext.Get<T>, чтобы решить проблемы с Autofac. Если вы погружаетесь в Microsoft.Owin.OwinContext.Get в Reflector, вы увидите, что он полностью поддерживается словарем вещей, которые вы регистрируете в среде. Это не динамика, и нет способа (без создания вашей собственной реализации IOwinContext), чтобы заставить ее разрешить вещи либо из словаря , либо из-за зависимости.

Если вы находитесь в DelegatingHandler или ApiController вы будете иметь ссылку на текущий HttpRequestMessage. Используйте message.GetDependencyScope(), чтобы получить текущую область зависимости уровня запроса для разрешения служб.

public HttpResponseMessage SomeControllerAction() 
{ 
    var service = this.Request.GetDependencyScope().GetService(typeof(Service)); 
} 

Если у вас есть доступ к HttpConfiguration, то вы можете использовать HttpConfiguration.DependencyResolver, чтобы разрешить ситуацию. Обратите внимание, что resolver будет не иметь зависимых от запроса запросов. Web API отслеживает область зависимостей запроса с входящим HttpRequestMessage, поэтому имейте в виду это ограничение. There is an FAQ about per-request lifetime scope, который поможет вам в этом.

Если вы находитесь в месте, где есть только в IOwinContext, вам, возможно, придется использовать пакет как CommonServiceLocator и associated Autofac.Extras.CommonServiceLocator. На самом деле нет способа получить ссылку на текущий HttpConfiguration или глобальный контейнер только с IOwinContext. Опять же, если вы пройдете этот маршрут, у вас не будет доступных зависимостей за запрос, поэтому имейте в виду.

+0

Да, вчера я взял источники реализации Katana и заметил реализацию OwinContext, который считывает ключи от объекта окружающей среды , Посмотрев содержимое среды, я заметил автозапуск: OwinLifetimeScope, который предоставляет доступ к текущей области Autofac. Я могу использовать это для решения моей службы. Метод расширения выполнил эту работу. Спасибо – bbeda

+2

Является ли это устаревшим @travis? 'owinContext.GetAutofacLifetimeScope()' работает. –

+1

Да, это новое расширение с момента ответа. –

4

Если у вас есть WebAPI в вашем проекте, вы можете имитировать запрос HTTP, как этот

var dependencyScope = new AutofacWebApiDependencyScope(owinContext.GetAutofacLifetimeScope()); 
var myService = dependencyScope.GetService(typeof(MyService)); 
Смежные вопросы