Как мне получить вспомогательный метод в служебном классе для использования его регистратора вызывающих абонентов в log4net?
Вопрос
У меня есть исполняемый файл, который в зависимости от поставляемого параметра командной строки выглядит примерно так:
Program.cs Программа.cs -
namespace DiskSpaceReporting
{
class Program
{
static void Main(string[] args)
{
if(args.Length == 1)
{
switch(args[0])
{
case "-summarytotals":
SummaryDiskSpaceReporter.Run();
break;
case "-detailed":
DetailedDiskSpaceReporter.Run();
break;
//...other reporting types
}
}
}
}
}
Резюме diskspacereporter.cs
namespace DiskSpaceReporting
{
public class SummaryDiskSpaceReporter
{
private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void Run()
{
log.Info(1234, "Starting");
//...do work
string message = Helpers.CreateMessage(messageID);
//...do work
}
}
}
Детализированный diskspacereporter.cs
namespace DiskSpaceReporting
{
public class DetailedDiskSpaceReporter
{
private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static void Run()
{
log.Info(1234, "Starting");
//...do work
string message = Helpers.CreateMessage(messageID);
//...do work
}
}
}
Помощники.cs
namespace DiskSpaceReporting
{
public class Helpers
{
private static IEventIDLog log = ???
public static string CreateMessage(Guid messageID)
{
log.Info(9876, "Starting");
//...do work
}
}
}
В моей конфигурации log4net у меня есть два отдельных регистратора, по одному для каждого из SummaryDiskSpaceReporter и DetailedDiskSpaceReporter, поскольку их требования к ведению журнала различны:
<root>
<level value="ALL" />
<appender-ref ref="ConsoleLogAppender" />
<appender-ref ref="EventLogAppender" />
</root>
<logger name="DiskSpaceReporting.SummaryDiskSpaceReporter">
<appender-ref ref="SummaryDiskSpaceReporterRollingFileAppender"/>
</logger>
<logger name="DiskSpaceReporting.DetailedDiskSpaceReporter">
<appender-ref ref="DetailedDiskSpaceReporterRollingFileAppender"/>
</logger>
Как SummaryDiskSpaceReporter, так и DetailedDiskSpaceReporter вызывают вспомогательный метод в классе, называемом Helpers.Я хочу поместить некоторые записи в методы вспомогательного класса.
Итак ... вопрос в том, как мне заставить помощников.Метод createMessage() использовать тот же регистратор, что и вызывающий его?
т. е.
SummaryDiskSpaceReporter.Run() -> использовать DiskSpaceReporting.SummaryDiskSpaceReporter подробный регистратор diskspacereporter.Run() -> использовать DiskSpaceReporting.Подробный diskspacereporter регистратор.
Приветствия Кев
Решение
Я играю с этим вопросом довольно долго и, к сожалению, вынужден на некоторое время сдаться и вернуться к выполнению "настоящей" работы.На данный момент то, что я придумал, заключается в следующем:
Варианты 1: Передайте регистратор в
Это не самый лучший вариант, но должен работать нормально, если вы не возражаете связать своего помощника с регистратором.Просто разрешите вашему методу createMessage использовать IEventIDLog.Затем вы можете использовать это для входа в систему с правильным паролем, переданным в logger.
public static string CreateMessage(Guid messageID, IEventIDLog log)
{
log.Info(9876, "Starting");
//...do work
}
Не совсем блестящий, но он должен сработать!
Варианты 2: Используйте стек вызовов
Используйте стек вызовов, чтобы найти вызывающий код, и из этого найдите тип и получите регистратор, который вы хотите от этого типа
public static string CreateMessage(Guid messageID)
{
StackFrame frame = new StackTrace().GetFrame(1);
IEventIDLog log = EventIDLogManager.GetLogger(frame.GetMethod().DeclaringType);
log.Info(9876, "Starting");
//...do work
}
Все еще не блестит, так как нам нужно прикоснуться к стеку вызовов и к тому, что произойдет, если в вызывающем коде нет регистратора.
Вариант 3: используйте log4net
Это тот вариант, который мы хотим использовать, черт возьми, это то, что вопрос хочет получить в качестве ответа, но я еще не разобрался с этим пока.:) Просматривая log4net, мы находим интересные вещи, такие как класс Hierarchy, который позволяет нам получить корневой регистратор.
Logger logger1 = ((log4net.Repository.Hierarchy.Hierarchy) log4net.LogManager.GetRepository()).Root;
Поэтому я уверен, что есть способ поднять регистратор на один уровень выше метода createMessage, теперь просто нужно его найти.:)