【问题标题】:Autofac not resolving model binder dependenciesAutofac 未解决模型绑定器依赖项
【发布时间】:2014-01-18 07:52:47
【问题描述】:

在我的容器中,我已经注册了 IModelBinder 和 Autofac 模型绑定器提供程序:

builder.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterWebApiModelBinderProvider();

我正在使用类本身的 ModelBinder 属性将我的模型绑定器绑定到一个类:

[ModelBinder(typeof(RequestContextModelBinder))]
public class RequestContext
{
    // ... properties etc.
}

还有模型绑定器本身,有依赖关系:

public class RequestContextModelBinder : IModelBinder
{
    private readonly ISomeDependency _someDependency;

    public RequestContextModelBinder(IAccountsRepository someDependency)
    {
        _someDependency = someDependency;
    }

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        // ... _someDependency is null
    }
}

通过控制器,我可以验证 Autofac 是否正确注入了 ISomeDependency 和模型绑定器。但是没有注入对模型绑定器的依赖。

当访问一个以 RequestContext 类作为参数的端点时,我得到了与模型绑定器相关的“无参数构造函数”异常。

有什么想法吗?


更新:

感谢 nemesv,事实证明,在 Web API 2 中调用 RegisterWebApiModelBinders 很可能没有任何意义。Autofac 的问题是 reported

要注册模型绑定器,需要调用:

builder.RegisterType<RequestContextModelBinder>().AsModelBinderForTypes(typeof(RequestContext));

【问题讨论】:

    标签: dependency-injection asp.net-web-api inversion-of-control autofac


    【解决方案1】:

    如果您在ModelBinderAttribute 中明确指定Type,则Wep.Api 会尝试从DependencyResolver 中获取具有给定类型的实例。

    但是 Autofac 使用 IModelBinder 接口注册模型绑定器类型,因此当 Wep.Api 尝试使用其具体类型解析您的绑定器时,解析失败并且 Wep.Api 将回退到 Activator.CreateInctance 以创建失败的模型绑定器实例在您的自定义构造函数上。

    您可以通过将 RequestContextModelBinder 注册为自己来解决此问题:

    builder.RegisterType<RequestContextModelBinder>().AsSelf();
    

    或者您可以从ModelBinderAttribute 中删除类型:

    [ModelBinder]
    public class RequestContext
    {
        // ... properties etc.
    }
    

    如果 ModelBinderAttribute 中没有给出类型,那么 Wep.API 会向当前的 ModelBinderProvider 询问您的模型类型的绑定器,在这种情况下,AutofacWebApiModelBinderProvider 将正确解析您的 RequestContextModelBinder

    但是,AutofacWebApiModelBinderProvider 只有在您正确注册后才能解析您的活页夹

    builder.RegisterType<RequestContextModelBinder>()
           .AsModelBinderForTypes(typeof (RequestContext));
    

    所以写RegisterWebApiModelBinders 是不够的,您在注册活页夹时需要使用AsModelBinderForTypes

    【讨论】:

    • 这是有道理的。但是我仍然无法使其工作。通过将 ModelBinderAttribute 更改为不包含特定类型,Autofac 似乎选择了正确的模型绑定器,但它仍然无法解决模型绑定器中的依赖关系。我得到“没有为此对象定义的无参数构造函数。”-错误。
    • 如果您仍然得到“没有为此对象定义无参数构造函数”。那么 Autofac 肯定不会拿起你的模型活页夹,否则你会得到一个不同的错误......
    • RegisterWebApiModelBinders 方法似乎无法正常工作。即使您没有在属性中指定类型,您也需要显式注册您的模型绑定器。但在这种情况下,您需要写:builder.RegisterType&lt;RequestContextModelBinder&gt;().AsModelBinderForTypes(typeof (RequestContext));。请尝试一下,如果它有效,那么我将使用此信息更新我的答案。
    • 做到了nemesv。非常感谢你。那你是说RegisterWebApiModelBinders扩展方法有bug?
    • 不知道是不是bug。 RegisterWebApiModelBinders 仍然注册您的活页夹,但没有注册 AutofacWebApiModelBinderProvider 所需的元数据。因为此功能在 Autofac 中完全没有记录,所以我不知道 RegisterWebApiModelBinders 方法适用于哪些用例...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多