DependencyResolver для каждого запроса в веб-API

В MVC создается экземпляр ModelValidatorProvider, который вызывается для проверки модели при каждом запросе. Это означает, что в среде DI он может принимать зависимости от объектов в пределах одного запроса, таких как единица работы или контекст базы данных. В веб-API это, по-видимому, было значительно изменено. Вместо того, чтобы создавать экземпляр для каждого запроса, ModelValidatorProvider кажется долгоживущим и создается при запуске приложения. Затем WebAPI кэширует результаты ModelValidatorProvider для каждого типа, что означает, что ModelValidator не может принимать никаких зависимостей от DI.

Я пытаюсь реализовать свой ModelValidator для использования фабрики с помощью локатора сервисов (пожалуйста, никаких автоматических комментариев «анти-шаблон»!). Это позволило бы мне создавать внутренний объект валидатора в каждом запросе, который мог бы получать зависимости от контейнера. Однако я не могу получить Rependency Resolver или контейнер, связанный с текущим запросом, из этого ModelValidator, который по существу относится к Singleton. Я пытался использовать GlobalConfiguration.Configuration.DependencyResolver, но это возвращает только глобальные службы (из корневой области, также здесь)

Я работаю в Autofac, поэтому подойдет решение, специфичное для autofac (например, MVC имеет AutofacDependencyResolver.Current, который внутренне использует DependencyResolver.GetService). В интеграции WebAPI нет эквивалента, предположительно из-за упомянутой выше причины, когда глобальный DependencyResolver возвращает только глобальные службы.

Причина, по которой я пытаюсь это сделать (а также для собственного использования), заключается в реализации интеграции веб-API для FluentValidation, которой в настоящее время не существует. До сих пор было две попытки, но ни одна из них не решает проблему внедрения зависимостей и вместо этого приводит к одному статическому ModelValidator.

Вещи, которые я пробовал до сих пор:

  • Использование GlobalConfiguration.Configuration.DependencyResolver (возвращает объекты из корневой области)
  • Использование зависимости от Func<IComponentContext> (всегда возвращает корневой контекст)

В ответе, который с тех пор был удален, было предложено удалить службу IModelValidatorProvider из конфигурации веб-API. Это должно было быть сделано с использованием отражения, так как интерфейс и классы реализации определены как внутренние, но это улучшило работу валидаторов (поскольку ModelValidator создавался для каждого запроса). Однако из-за использования отражения для проверки наличия валидаторов в модели и всех ее свойств происходит значительное снижение производительности, поэтому я не хочу использовать этот вариант.

В ответе Филипа В. предлагается использовать HttpRequestMessage для получения области зависимости, но я не нашел ничего такого, как HttpRequestMessage.Current, который обеспечивал бы доступ к этому объекту из долгоживущего объекта - если бы это могло быть достигнуто, я считаю, что все встало бы на свои места.


person Richard    schedule 22.02.2013    source источник


Ответы (1)


Чтобы получить текущую область зависимостей, вы должны использовать (сюрприз, сюрприз :) GetDependencyScope() текущей HttpRequestMessage (подробнее о которой вы можете прочитать в в MSDN) вместо GlobalConfiguration.

Я написал в блоге о веб-API за -запросить область зависимости некоторое время назад - это должно быть полезно.

person Filip W    schedule 22.02.2013
comment
Похоже, это ближе к решению, но как я могу получить HttpRequestMessage? Это из давно работающего класса. Гугление подсказывает, что это тоже невозможно. - person Richard; 22.02.2013