As a reply to an earlier question (Accessing ILogger from non-Controller classes in Class Libary .NET Core 3), we can inject the dependent class into the controller. The DI Container resolves dependencies on registration of Transient services at the time of Startup. Hence if a ClassA is instantiated by a Controller, as a result of this mechanism, we can access ILogger in Class A.
Original question code sample:
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
services.AddLogging();
services.AddTransient<ClassX>();
...
}
}
public class ControllerB : ControllerBase
{
private readonly ClassX classX;
private readonly ILogger logger;
public ControllerB(ClassX classX, ILogger<ControllerB> logger)
{
this.classX = classX;
this.logger = logger;
}
...
}
public class ClassX
{
private readonly ILogger logger;
public ClassX(ILogger<ClassX> logger)
{
this.logger = logger;
}
}
Now I have a scenario as below, where the constructor of ClassX
has multiple parameters:
public class ClassX
{
private readonly ILogger logger;
private int _num1;
public ClassX(ILogger<ClassX> logger, int num1)
{
this.logger = logger;
this.num1 = num1;
}
}
Constructor of ClassX
made available to .NET Core DI container through [ActivatorUtilitiesConstructor]
:
[ActivatorUtilitiesConstructor]
public ClassX(int num)
{
this.constructorNum = num;
}
So we need to inject the constructor parameters during DI resolution at Startup. I tried this
services.AddTransient<Func<int, ClassX>>((provider) =>
{
return new Func<int, ClassX>((numParam) => new ClassX(numParam));
});
But this throws an error as we are not passing the ILogger.
How do I inject the ILogger as well as the constructor parameters at runtime through DI?
For this scenario, you can use the provider
parameter that's being passed into the factory function to resolve an instance of ILogger<ClassX>
from the IoC container:
services.AddTransient<Func<int, ClassX>>((provider) =>
{
return new Func<int, ClassX>((numParam) =>
new ClassX(provider.GetRequiredService<ILogger<ClassX>>(), numParam));
});
provider
here is an implementation of IServiceProvider
. This example uses an extension method, GetRequiredService
, to retrieve an instance of ILogger<ClassX>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With