Best is to use ILogger<T>
only in your application layer (Controllers, application services - but not domain services).
If you want to add logging around your domain services/repositories, it'd be best to create decorators for it. This only works well if you have abstracted your interfaces from their implementations and use/inject interfaces everywhere).
However, there are limitations on what you can do with decorators. You can log before and after the call to a method defined in the public interface. Not inside the call.
Why avoid logging/injecting your logger into the service?
Coupling
You should avoid injecting ILogger<T>
in your domain objects, as this couples your domain to ASP.NET Core logging framework/base classes. However, you can always define your own logger interface to use it within your domain and implement it as wrapper around ILogger<T>
.
SOLID Principle
S in SOLID principle stand for SRP (Single Responsibility Principle) and says, one object should just have one and only one responsibility. Doing logging and persistence or businesses logic into one object violates this principle.
But in the end, you got to weight up costs of development with the benefits you gain with it. If it's a long living application (to be used for the next 10 years or so) and a complex one, logging as decorators makes sense for sure. If it's a small project with only a few weeks of development time, the benefit of this abstraction may not outweigh the costs.