Sedat Kapanoglu
Sedat Kapanoglu

Reputation: 47641

How to pass logger instance to my custom ModelBinderProvider in ConfigureServices?

I want to use ASP.NET Core's own logging and DI mechanism to perform some debug logging and tracing in my code. So my ModelBinderProvider looks like this:

public class MyOwnModelBinderProvider: // ... bla bla 
{
    public MyOwnModelBinderProvider(ILogger<MyOwnModelBinderProvider> logger)
    {
       // .. bla bla
    }
}

The recommended way to set up custom ModelBinderProviders in Startup.cs is like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersAndViews(configure => 
        configure.ModelBinderProviders.Insert(0, 
            new MyOwnModelBinderProvider(/** WHAT TO PUT HERE? **/)));
}

I researched this and people have been creating separate instances of service providers by calling BuildServiceProvider in the ConfigureServices method but David Fowler was strictly against that as it might create a hanging instance of a service provider collection, never-freed.

It feels like quite an overhead for me too, just to pass a logger instance. Am I missing an obvious pattern here? I'm feeling like it should be much easier.

Upvotes: 2

Views: 1280

Answers (1)

davidfowl
davidfowl

Reputation: 38764

I can think of 2 ways to do this:

  1. In GetBinder the ModelBinderProviderContext has a Services property.
  2. You can configure MvcOptions outside of the call to AddControllersAndViews:
builder.Services.AddOptions<MvcOptions>()
                .Configure<ILoggerFactory>((options, loggerFactory) =>
                {
                    options.ModelBinderProviders.Add(new MyOwnModelBinderProvider(loggerFactory));
                });

This lets you pass dependencies to things that are created via options.

Upvotes: 4

Related Questions