在 MVC 中,一个ModelValidatorProvider
被实例化并调用以验证每个请求的模型。这意味着在 DI 环境中,它可以依赖于单个请求范围内的对象,例如工作单元或数据库上下文。在 Web API 中,这似乎已经发生了重大变化。不是按请求实例化,ModelValidatorProvider
似乎是长期存在的,并在应用程序启动时实例化。然后 WebAPI 缓存结果ModelValidatorProvider
每个类型,这意味着ModelValidator
无法从 DI 获取任何依赖项。
我正在努力实施我的ModelValidator
使用服务定位器来使用工厂(请不要自动添加“反模式”注释!)。这将允许我在每个请求中构造一个内部验证器对象,该对象能够从容器中获取依赖项。但是,我无法从此范围内获取范围为当前请求的依赖关系解析器或容器ModelValidator
它本质上属于单例。我尝试过使用GlobalConfiguration.Configuration.DependencyResolver
,但这仅返回全局范围的服务(从根范围,也这里提到 https://stackoverflow.com/a/11151148/163495)
我在 Autofac 工作,因此特定于 autofac 的解决方案将是合适的(例如 MVC 有AutofacDependencyResolver.Current
,其内部使用DependencyResolver.GetService
)。 WebAPI 集成中没有可用的等效项,大概是由于上述原因,全局DependencyResolver
仅返回全球范围的服务。
我尝试这样做的原因(以及我自己的使用)是为了实现 FluentValidation 的 Web API 集成,而该集成目前还不存在。到目前为止,已经有两次尝试,但都没有处理依赖注入问题,而是产生了单个静态 ModelValidator。
到目前为止我尝试过的事情:
- Using
GlobalConfiguration.Configuration.DependencyResolver
(从根范围返回对象)
- 依赖于
Func<IComponentContext>
(始终返回根上下文)
在已被删除的答案中,建议删除IModelValidatorProvider
来自 Web API 配置的服务。这必须使用反射来完成,因为接口和实现类都定义为内部的,但它确实使验证器工作得更好(因为 ModelValidator 是根据请求构造的)。但是,由于使用反射来检查模型及其具有的每个属性上的验证器,因此这样做会严重影响性能,因此我不想采用此选项。
Filip W 的回答建议使用 HttpRequestMessage 来获取依赖范围,但我没有找到诸如HttpRequestMessage.Current
这将提供从一个长期存在的对象中访问该对象的机会 - 如果可以实现这一点,我相信一切都会就位。
要获取当前依赖范围,您必须使用 (惊喜,惊喜:)GetDependencyScope()
当前的HttpRequestMessage
(更多相关内容您可以阅读on MSDN http://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessageextensions.getdependencyscope%28v=vs.108%29.aspx) 代替GlobalConfiguration
.
我在博客上写过Web API 每个请求的依赖范围 http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/不久前 - 这应该会有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)