We have existing services where interface for Logging is injected into Child constructors and passed on to its parents (base).
Existing:
Public class Child: Parent
public Ctor(ILogger logger) : base(ILogger logger)
New: (Modified ILogger to IMyLogger which internally uses Serilog Logger APIs for logging)
Public class Child: Parent
public Ctor(IMyLogger<Child> logger) : base(IMyLogger<Parent> logger)
The above will obviously not work. But I need to work around this because these constructors are mostly used only Unittesting purposes or to retain a certain hierarchy chain which will be used while registering with DI framework!
Why I need to introduce a generic Logger is to bind a type to the Logger implementation which I can use later as my Serilog Source Context.
2 ways I can fix the above refactoring:
Options
- Retain
ILogger
and not make in Generic. UseStackFrames
to find the caller Type and assign it toSourceContext
which will later be logged - Refactor
ILogger
toILogger<T>
but not pass the logger to base constructor.
Public class Child: Parent
public Ctor(ILogger<Child> logger) : base()
Option 1 uses reflection and we can never rely on the Stack Frames to find the correct method which made the Logging call. Also performance will be impacted.
I feel option 2 is a cleaner way where each Child
will have its own Context
based Logger<Myself>
which can later be mocked in Unit Tests.
Loggers should be one each for each service I feel. But am open to get pounded by varying thoughts and other better ways to handle this design. :-)