A very common logging goal I find in various projects, is that any class/object which creates a log entry will record its own class/object name into that entry. If the log entry is for an exception and stack-trace, that information is included for free. But if the log entry is not for an exception, then a variety of other approaches are typically used to obtain this result:
- Hard-code a const field into each class, which holds the name of the class (or the logger itself!). The logger is given that const when logging.
- The logger is wrapped with code that reflects the call stack, to determine which class had made the logging invocation. The name is then added to the log entry.
- Each class is injected with a logger instance which already knows the name of the class in which it is injected.
A simple example of #3 looks like this:
ILogger logger = new MyLogger("AmazingClass");
IAmazingClass foo = new AmazingClass(logger);
What I would like to know is if any IOC container, particularly Unity, is capable of helping to solve this "scenario #3" elegantly? If yes, how?
I feel the answer should be simple: the IOC container "knows" which class it is about to construct and inject, and offers that "dependor" information to the "dependee" before it finishes resolving the type.
For example, perhaps Unity could accomplish this through delegate registration and a "reverse reflection" registration like this:
var container = new UnityContainer();
container.RegisterType<ILogger, MyLogger>(new InjectionFactory(
(Type targetOfInjection) => new MyLogger(targetOfInjection.Name)
);
I made up that syntax, but it is entirely believable. That said, what in reality does Unity (or another IOC container) offer for proposed capability?
p.s. I personally am "ok" with my logger and logging making no attempt to capture the class/object names for non-exception entries. Keeps the code simpler. But if I am forced to do this approach, I usually take the stack-reflection option (scenario #2). It would be interesting to know what other approaches people favor when they too are required to capture class names in non-exception logging statements. Ultimately, however, this question focuses on using an IOC container.