Как мне спроектировать ведение журнала в моем приложении?

Итак, я провел много исследований по этому поводу и не нашел ответов, на которые я бы сказал «да, ЭТО». Я надеюсь, что постоянно эрудированные специалисты по StackOverflow смогут мне помочь.

Я сталкивался с этой проблемой в нескольких различных сценариях. Скажем, у меня есть приложение C #, и есть важные вещи, которые я хочу регистрировать.

public class MyClass
{
    ... 

    public void ImportantMethod()
    {
        DoInterestingThing();

        var result = SomethingElseImportant();
        if (result == null)
        {
            logger.Log("I wasn't expecting that. No biggie.");
            return;
        }

        MoreInterestingStuff(); 
}

Меня интересует где взять регистратор из .

] Насколько я понимаю, у меня есть несколько вариантов.

  1. Внедрить его в MyClass в конструкторе.
  2. Получить его, используя глобально доступный локатор служб.
  3. Используйте декораторы методов и АОП, чтобы вести журнал за меня. .

Ни один из этих вариантов не кажется отличным. №3 кажется невозможным, поскольку я веду журнал прямо в середине своей бизнес-логики, а не просто выполняю простую трассировку вызовов моих методов, входных параметров и / или возникших исключений. # 2, хотя кажется, что это просто, модульное тестирование было бы действительно сложно. Конечно, я бы хотел все провести модульное тестирование. №1, хотя он будет работать нормально, загромождает всю мою бизнес-логику объектами ведения журнала , которые не имеют ничего общего с самими бизнес-объектами.

Есть ли альтернативные идеи или мысли по одному из вышеперечисленных вариантов? Большое спасибо!

РЕДАКТИРОВАТЬ: для ясности, я уже знаю, как делать DI (я использую Unity), и я уже знаю хорошую структуру ведения журнала (я использую log4net). Просто интересно, как использовать ведение журнала в архитектурном смысле в приложении наиболее разумным способом.


* EDIT *

Я отметил ответ Марка Симана как решение. Я просмотрел свое приложение и обнаружил, что большинство моих вызовов журналирования делали то же самое, что и декоратор. А именно, регистрируйте запись в методе, все созданные исключения и возвращаемые значения выхода.

В некоторых случаях мне все же приходилось регистрироваться непосредственно внутри метода. Примером может быть ситуация, когда я хочу быстро выйти из строя в методе, который ничего не возвращает, но не генерирует исключение . В этих случаях у меня есть синглтон, содержащий ссылку на LogProvider , который, в свою очередь, будет извлекать именованный экземпляр журнала. Код выглядит примерно так:

private ILog logger = LogProviderFactory.Instance.GetLogger(typeof(Foo));

LogProviderFactory имеет метод SetProvider , который позволяет вам заменять синглтон. Итак, в модульном тестировании я могу:

// LogProviderFactory.Instance now is our mock
LogProviderFactory.SetProvider(MockLogProvider);

Декоратор журналирования использует тот же LogProvider, что и синглтон (который он получает через инъекцию), поэтому ведение журнала унифицировано по всей системе.

Таким образом, на самом деле конечным решением в основном был вариант №3 , и гибрид № 2 (где это шаблон локатора службы, но служба «вводится» в локатор).

AOP

Что касается «аспектно-ориентированного программирования», я был немного разочарован ограничениями языка. Надеясь, что АОП будет рассматриваться как первая-класс гражданин в будущих выпусках.

  • Я попробовал PostSharp, но не смог правильно запустить его на моем компьютере. Вдобавок было большим ограничением то, что вам нужно было установить PostSharp в вашей системе, чтобы использовать его (в отличие от простого вызова dll, поставляемого с решением, или чего-то подобного).
  • Я использовал LinFu и смог частично заставить его работать. Однако в нескольких случаях он взорвался. Новый выпуск 2.0 практически не задокументирован, так что это было препятствием.
  • Однако перехват интерфейса с Unity работает нормально из коробки. Мне повезло, что большинство вещей, которые я хотел регистрировать, были в классах, реализующих интерфейсы.

5
задан Community 23 May 2017 в 11:54
поделиться