在MVC中,实例化一个ModelValidatorProvider
并调用它以验证每个请求上的模型。这意味着在DI环境中,它可以依赖于单个请求范围内的对象,例如工作单元或数据库上下文。在Web API中,这似乎发生了重大变化。代替每个请求实例化,ModelValidatorProvider
似乎是在应用程序启动时长期存在和实例化的。 WebAPI然后缓存来自每个类型的ModelValidatorProvider
的结果,这意味着ModelValidator
不能从DI获得任何依赖关系。Web API中的每个请求依赖关系解析器
我想实现我的ModelValidator
使用服务定位器的工厂(请不要自动'反模式'的意见!)。这将允许我在每个请求中构造一个内部验证器对象,这将能够从容器中获取依赖关系。但是,我无法得到这个ModelValidator
中的当前请求范围内的依赖项解析器或容器,它基本上被定义为一个Singleton。我试着用GlobalConfiguration.Configuration.DependencyResolver
,但是这只是回报全球范围的服务(从根范围内,也mentioned here)
我在Autofac工作,所以一个特定autofac的解决方案将是合适的(如MVC有AutofacDependencyResolver.Current
,内部使用DependencyResolver.GetService
)。 WebAPI集成中没有可用的等价物,可能是因为上述原因,全球范围内的服务仅返回全局范围的服务。
我试图做到这一点(以及为了我自己的用途)的原因是为FluentValidation实现Web API集成,目前它不存在。到目前为止有两次尝试,但都没有处理依赖注入问题,而是导致一个静态的ModelValidator。
事情我试过到目前为止:
- 使用
GlobalConfiguration.Configuration.DependencyResolver
(返回从根范围对象) - 承担
Func<IComponentContext>
(总是返回根上下文)
的依赖在一个已被删除的答案,建议从Web API配置中删除IModelValidatorProvider
服务。这必须使用反射来完成,因为接口和实现类都被定义为内部的,但它确实使验证器更好地工作(因为ModelValidator是根据请求构造的)。但是,由于使用了反射来检查模型上的验证器以及它的每个属性,所以这样做会产生显着的性能影响,所以我不想采用此选项。
菲利普W公司的答案建议使用HttpRequestMessage得到相关范围,但我没有发现任何诸如HttpRequestMessage.Current
这将提供从长寿命对象中访问该对象 - 如果这可以实现,我相信一切都会到位。
听起来像它可能更接近解决方案,但我如何获得HttpRequestMessage?这是来自长时间运行的课程。谷歌搜索表明这也是不可能的。 – Richard 2013-02-22 16:40:26