Currently I have the function CreateLog() for creating a a log4net Log with name after the constructing instance's class. Typically used as in:
class MessageReceiver
{
protected ILog Log = Util.CreateLog();
...
}
If we remove lots of error handling the implementation boils down to: [EDIT: Please read the longer version of CreateLog further on in this post.]
public ILog CreateLog()
{
System.Diagnostics.StackFrame stackFrame = new System.Diagnostics.StackFrame(1);
System.Reflection.MethodBase method = stackFrame.GetMethod();
return CreateLogWithName(method.DeclaringType.FullName);
}
Problem is that if we inheirit MessageReceiver into sub classes the log will still take its name from MessageReceiver since this is the declaring class of the method (constructor) which calls CreateLog.
class IMReceiver : MessageReceiver
{ ... }
class EmailReceiver : MessageReceiver
{ ... }
Instances of both these classes would get Logs with name "MessageReceiver" while I would like them to be given names "IMReceiver" and "EmailReceiver".
I know this can easily be done (and is done) by passing a reference to the object in creation when calling CreateLog since the GetType() method on object does what I want.
There are some minor reasons to prefer not adding the parameter and personally I feel disturbed by not finding a solution with no extra argument.
Is there anyone who can show me how to implement a zero argument CreateLog() that gets the name from the subclass and not the declaring class?
EDIT:
The CreateLog function does more than mentioned above. The reason for having one log per instance is to be able to differ between different instances in the logfile. This is enforced by the CreateLog/CreateLogWithName pair.
Expanding on the functionality of CreateLog() to motivate its existence.
public ILog CreateLog()
{
System.Diagnostics.StackFrame stackFrame = new System.Diagnostics.StackFrame(1);
System.Reflection.MethodBase method = stackFrame.GetMethod();
Type type = method.DeclaringType;
if (method.IsStatic)
{
return CreateLogWithName(type.FullName);
}
else
{
return CreateLogWithName(type.FullName + "-" + GetAndInstanceCountFor(type));
}
}
Also I prefer writing ILog Log = Util.CreateLog(); rather than copying in some long cryptic line from an other file whenever I write a new class. I am aware that the reflection used in Util.CreateLog is not guaranteed to work though - is System.Reflection.MethodBase.GetCurrentMethod() guaranteed to work?