Actualmente tengo la función CreateLog() para crear un log4net Log con nombre después de la clase de la instancia de construcción. Normalmente se utiliza como en:¿Cómo encuentro el tipo de instancia de objeto de la persona que llama de la función actual?
class MessageReceiver
{
protected ILog Log = Util.CreateLog();
...
}
Si quitamos un montón de manejo de la aplicación de error se reduce a: [EDIT:. Por favor leer la versión más larga de CreateLog más adelante en este post]
public ILog CreateLog()
{
System.Diagnostics.StackFrame stackFrame = new System.Diagnostics.StackFrame(1);
System.Reflection.MethodBase method = stackFrame.GetMethod();
return CreateLogWithName(method.DeclaringType.FullName);
}
El problema es que si incluimos MessageReceiver en subclases, el registro seguirá tomando su nombre de MessageReceiver ya que esta es la clase de declaración del método (constructor) que llama a CreateLog.
class IMReceiver : MessageReceiver
{ ... }
class EmailReceiver : MessageReceiver
{ ... }
Las instancias de ambas clases obtendrían los registros con el nombre "MessageReceiver", mientras que me gustaría que fueran nombres dados "IMReceiver" y "EmailReceiver".
Sé que esto se puede hacer fácilmente (y se hace) pasando una referencia al objeto en la creación al llamar a CreateLog ya que el método GetType() en el objeto hace lo que quiero.
Existen algunas razones menores para preferir no agregar el parámetro y personalmente me molesta no encontrar una solución sin argumentos adicionales.
¿Hay alguien que pueda mostrarme cómo implementar un argumento cero CreateLog() que obtiene el nombre de la subclase y no de la clase declarante?
EDIT:
La función CreateLog hace más que se mencionó anteriormente. La razón para tener un registro por instancia es poder diferir entre diferentes instancias en el archivo de registro. Esto se aplica mediante el par CreateLog/CreateLogWithName.
Ampliando la funcionalidad de CreateLog() para motivar su existencia.
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));
}
}
También prefiero escribir ILog Log = Util.CreateLog(); en lugar de copiar en una línea críptica larga de otro archivo cada vez que escribo una nueva clase. Soy consciente de que la reflexión utilizada en Util.CreateLog no está garantizada, ¿está garantizado que funciona System.Reflection.MethodBase.GetCurrentMethod()?
System.Diagnostics.StackFrame stackFrame = new System.Diagnostics.StackFrame (1); debe ser el mismo que: System.Diagnostics.StackFrame [] frames = new System.Diagnostics.StackTrace.GetFrames(); System.Diagnostics.StackFrame stackFrame = frames [1]; – notso
eso es cierto, solo pensé que mostrarle cómo obtener toda la matriz en una sola llamada podría ser útil. –