Reputation: 2361
In my container I've registered my IModelBinder's and the Autofac model binder provider:
builder.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterWebApiModelBinderProvider();
I'm binding my model binder to a class using the ModelBinder attribute on the class itself:
[ModelBinder(typeof(RequestContextModelBinder))]
public class RequestContext
{
// ... properties etc.
}
And the model binder itself, with a dependency:
public class RequestContextModelBinder : IModelBinder
{
private readonly ISomeDependency _someDependency;
public RequestContextModelBinder(IAccountsRepository someDependency)
{
_someDependency = someDependency;
}
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
// ... _someDependency is null
}
}
From a controller, I can verify that Autofac correctly injects both the ISomeDependency and the model binder. However the dependency on the model binder is not injected.
When accessing an endpoint that has the RequestContext class as a parameter, I'm getting the "No parameterelss constructor"-exception, that relates to the model binder.
Any ideas?
Thanks to nemesv, it turns out that it most likely doesn't make any sense to call RegisterWebApiModelBinders
in Web API 2. An issue has been reported to Autofac.
To register model binders, one needs to call:
builder.RegisterType<RequestContextModelBinder>().AsModelBinderForTypes(typeof(RequestContext));
Upvotes: 4
Views: 2329
Reputation: 139788
If you explicitly specify a Type
in the ModelBinderAttribute
then Wep.Api tries to get an instance with the given type form the DependencyResolver
.
However Autofac registers the model binder types with IModelBinder
interface so when Wep.Api tries to resolve your binder with its concrete type the resolution fails and Wep.Api will fallback to Activator.CreateInctance
to create the model binder instance which fails on your custom constructor.
You can fix this with registering your RequestContextModelBinder
as self:
builder.RegisterType<RequestContextModelBinder>().AsSelf();
Or you can just remove the type from the ModelBinderAttribute
:
[ModelBinder]
public class RequestContext
{
// ... properties etc.
}
If there is no type given in the ModelBinderAttribute
then Wep.API asks the current ModelBinderProvider
for a binder for your model type which in this case the AutofacWebApiModelBinderProvider
which will resolve your RequestContextModelBinder
correctly.
However the AutofacWebApiModelBinderProvider
only resolves your binder if you have correctly registered it with
builder.RegisterType<RequestContextModelBinder>()
.AsModelBinderForTypes(typeof (RequestContext));
So writing RegisterWebApiModelBinders
is not enough your need to use the AsModelBinderForTypes
when registering your binders.
Upvotes: 4