I'm trying to add ModelStateInvalidFilter
as a global filter so that I don't have to add ApiController
attribute on every controllers.
This is what I'm doing in my Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ApiBehaviorOptions>();
services.AddScoped<ModelStateInvalidFilter>();
services.AddMvc(config => config.Filters.AddService<ModelStateInvalidFilter>())
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
However, I'm getting this error
InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter'.
I know the generic ILogger<T>
is automatically injected by the framework but how do I inject the non-generic ILogger
which is a dependency of the ModelStateInvalidFilter
class?
When you use [ApiController]
, ModelStateInvalidFilter
isn't resolved from the DI container, it's created with new
:
_modelStateInvalidFilter = new ModelStateInvalidFilter(
apiBehaviorOptions.Value,
loggerFactory.CreateLogger<ModelStateInvalidFilter>());
In order to be able to resolve this from the DI container, we'll need to be a bit more explicit about how we create an instance of ILogger
, which can be done when adding ModelStateInvalidFilter
to the DI container, like this:
services.AddScoped<ModelStateInvalidFilter>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
return new ModelStateInvalidFilter(
sp.GetRequiredService<ApiBehaviorOptions>(),
loggerFactory.CreateLogger<ModelStateInvalidFilter>());
});
In this example, sp
is the instance of IServiceProvider
that we can use to request services from the DI container. ILoggerFactory
has already been registered for us, so we can request it and use it in the same way shown in the first code snippet above.