Reputation: 790
We use Simple Injector in ASP.NET Core application. Recently we've decided to use Serilog for logging purposes.
Configuration was done in Program.cs as stated in their documentation. Then, in order to make Simple Injector able to resolve ILoggerFactory
I did something like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
// As per my understanding, we force SimpleInjector to use
// ILoggerFactory registration from IApplicationBuilder
container.CrossWire<ILoggerFactory>(app)
}
After that ILoggerFactory
can be injected wherever we use it. And it works fine (creates new instances ILogger<T>
).
But this is annoying, to create instance from factory every time we need.
It would be better to get ILogger<T>
directly in dependent class, instead of ILoggerFactory
.
So, how can I register ILogger<T>
to get instance in case like below?
public class HelloWorldController : Controller
{
public HelloWorldController(ILogger<HelloWorldController> logger)
{
// ...
}
}
Upvotes: 7
Views: 3311
Reputation: 172646
Although Alsami's answer would work, use the following registration instead:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
// This next call is not required if you are already calling AutoCrossWireAspNetComponents
container.CrossWire<ILoggerFactory>(app);
This exact example is shown in the documentation.
This registration allows injecting the Logger<T>
into a non-generic ILogger
constructor argument, where the T
of Logger<T>
becomes the type the logger is injected into. In other words, when HelloWorldController
depends on ILogger
, it will get injected with a Logger<HelloWorldController>
. This means you can simplify your HelloWorldController
to the following:
public class HelloWorldController : Controller
{
public HelloWorldController(ILogger logger)
{
// ...
}
}
By letting your application components depend on ILogger
rather than ILogger<T>
you:
Upvotes: 7
Reputation: 9815
You also have to register the logger iteself as a generic type. I don't know simple injector but this should be the correct syntax.
container.Register(typeof(ILogger<>), typeof(Logger<>), Lifestyle.Singleton);
Upvotes: 3