【问题标题】:Per-Request DependencyResolver in Web APIWeb API 中的每个请求的 DependencyResolver
【发布时间】:2013-02-25 05:15:19
【问题描述】:

在 MVC 中,ModelValidatorProvider 被实例化并调用以验证每个请求的模型。这意味着在 DI 环境中,它可以依赖于单个请求范围内的对象,例如工作单元或数据库上下文。在 Web API 中,这似乎已经发生了重大变化。 ModelValidatorProvider 似乎是长期存在的,并在应用程序启动时被实例化,而不是按请求实例化。然后,WebAPI 缓存每个类型的 ModelValidatorProvider 的结果,这意味着 ModelValidator 不能从 DI 获取任何依赖项。

我正在尝试实现我的ModelValidator 以使用使用服务定位器的工厂(请不要使用自动“反模式”cmets!)。这将允许我在每个请求中构造一个内部验证器对象,它能够从容器中获取依赖项。但是,我无法从这个ModelValidator 中获取范围为当前请求的依赖解析器或容器,该ModelValidator 本质上是一个单例。我试过使用GlobalConfiguration.Configuration.DependencyResolver,但这只会返回全局范围的服务(从根范围,也有mentioned here

我在 Autofac 工作,因此特定于 autofac 的解决方案是合适的(例如 MVC 有 AutofacDependencyResolver.Current,它在内部使用 DependencyResolver.GetService)。 WebAPI 集成中没有等效的可用,大概是因为上面提到的原因,全局 DependencyResolver 只返回全局范围的服务。

我尝试这样做(以及我自己使用)的原因是为了实现 FluentValidation 的 Web API 集成,目前不存在。到目前为止已经进行了两次尝试,但都没有处理依赖注入问题,而是产生了一个静态 ModelValidator。

到目前为止我尝试过的事情:

  • 使用GlobalConfiguration.Configuration.DependencyResolver(从根范围返回对象)
  • 依赖Func<IComponentContext>(总是返回根上下文)

在一个已被删除的答案中,建议从 Web API 配置中删除 IModelValidatorProvider 服务。这必须使用反射来完成,因为接口和实现类都定义为内部的,但它确实使验证器工作得更好(因为 ModelValidator 是根据请求构造的)。但是,由于使用反射来检查模型上的验证器及其具有的每个属性,因此这样做会对性能造成重大影响,因此我不想采用此选项。

Filip W 的回答建议使用 HttpRequestMessage 来获取 Dependency Scope,但我没有找到诸如 HttpRequestMessage.Current 之类的任何东西,它可以从长期存在的对象中提供对该对象的访问 - 如果可以实现的话,我相信一切会到位。

【问题讨论】:

    标签: asp.net-web-api autofac fluentvalidation


    【解决方案1】:

    要获得当前的依赖范围,您必须使用当前HttpRequestMessageGetDependencyScope() (您可以阅读on MSDN)而不是GlobalConfiguration

    我不久前在博客上写过Web API per-request dependency scope - 这应该会有所帮助。

    【讨论】:

    • 听起来可能更接近解决方案,但是如何获取 HttpRequestMessage 呢?这是来自一个长期运行的课程。谷歌搜索表明这也是不可能的。
    猜你喜欢
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多