0
votes

How do I inject the type of a class into one of its dependencies using the built in ASP.Net dependency injection?

In Startup.Configure I have:

services.AddTransient<ILogger>(x => new Logger(???));

And my class takes a Logger instance

public class ExampleController : ControllerBase
{
    public Example(ILogger logger)
    {
        ...
    }
}

The Logger constructor should receive typeof(Example) where I have written "???", except this should work for all classes that receive a logger.

The question is very similar to this but I am using an in-house ILogger interface and Logger class, and not using ninject. I effectively wan't to duplicate ninject's "context.Request.ParentContext.Plan.Type" in the other question.

2
Which logger are you using, also what is above Example? Because Example : Controller vs Example work very differently with the built in DI Container for Core. - Greg
I have updated my code and question to clarify. Yes, the class should be a controller. The logger is not Microsoft.Extensions.Logging. - Tom
is it Serilog by chance? - Greg

2 Answers

4
votes

I'm assuming you're using Microsoft.Extensions.Logging. With that at least, there's no need to register anything. The logging is already set up via the call to CreateDefaultBuilder() in Program.cs. The most you'd need to do is add alternate/additional logging providers, but that's config. You'd never call something like services.AddTransient with ILogger.

Instead, you handle the type param of the ILogger interface via the param you're using to inject it:

public class Example
{
    public Example(ILogger<Example> logger)
    {
        ...
    }
}

You can still store it in a simple ILogger ivar, without a generic type, but the param you're injecting into needs to specify the type param.

Alternatively, if you're looking for something a little more flexible, you can inject ILoggerFactory instead, and then use GetType() to provide the type:

public class Example
{
    private readonly ILogger _logger;

    public Example(ILoggerFactory loggerFactory)
    {
        _logger = _loggerFactory.CreateLogger(GetType())
    }
}
1
votes

One of available solutions is:

Initialize your logger (NLog, Log4Net, you-name-it) like this:

WebHost.ConfigureLogging((context, builder) => ...init your logger engine here...)

Then, use generic version of ILogger<> instead of just ILogger type:

public class Example
{
    public Example(ILogger<Example> logger)
    {
        ...
    }
}

Hope this helps.