В 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
, который обеспечивал бы доступ к этому объекту из долгоживущего объекта - если бы это могло быть достигнуто, я считаю, что все встало бы на свои места.