Итак, я провел много исследований по этому поводу и не нашел ответов, на которые я бы сказал «да, ЭТО». Я надеюсь, что постоянно эрудированные специалисты по 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();
}
Меня интересует где взять регистратор
из .
] Насколько я понимаю, у меня есть несколько вариантов.
Ни один из этих вариантов не кажется отличным. №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
Что касается «аспектно-ориентированного программирования», я был немного разочарован ограничениями языка. Надеясь, что АОП будет рассматриваться как первая-класс гражданин в будущих выпусках.