ASP.NET Core has built-in support for logging, but the documentation states that logging should be done by requesting an ILogger
via dependency injection, i.e. by adding it as an argument to the Controller
constructor.
Polluting method signatures or constructors throughout my code with ILogger
arguments feels like the wrong solution for this cross-cutting concern. In Android the Log
class is static, making it trivial to log from any part of the code.
What would be a good way to do logging from other places than the controller?
Regarding using logging in any component:
If your
CustomClass
is a data container (DTO class), it should not know about logging, but just contain data.For other classes with names like "Service" , "Provider", "Handler" and so on, the best practices is to resolve instances using dependency injection. In general, you should use DI wherever it is possible, as it’s a technique for achieving loose coupling between objects and their collaborators or dependencies. For more information, the following question might be interesting: Should I use Dependency Injection or static factories?
So simply add
ILogger<CustomClass>
to its constructor (actually the same way, as you do for controllers), as .NET Core supports only constructor injection by default:ASP.NET Core’s built-in dependency injection container will automatically resolved transient dependencies. So if your controller has class
A
as a dependency that uses classB
where you want to log something, your code can be something like this:Note that you also need to register the dependencies in
Startup
usingIServiceCollection.Add…
methods:Built-in logging support means that .NET Core out of the box knows about and is using built-in abstractions for logging. This is mainly done by
ILoggerFactory
andILoggerProvider
interfaces.Using your own
ILoggerProvider
implementation, you can add your own logger that can do whatever you want. You can check the NLog logger implementation as working example.And thanks to
ILoggerFactory
, you can simply configure your Logger for project-specific purposes:This article indicates that you should use DI to inject your logger in all classes that need it: https://docs.asp.net/en/latest/fundamentals/logging.html
On the other hand, here is an article (Microsoft sponsored) that mentions a global static reference approach: https://msdn.microsoft.com/en-us/magazine/mt694089.aspx?f=255&MSPPError=-2147217396
Not trying to stoke the Static vs. DI vs. Service Locator: Pattern or Anti-pattern debates, I personally find common cross-cutting concerns such as logging and configuration to be candidates for this latter approach, but have used both in the past.