Здравствуйте, LWhisper, Вы писали:
LW>Всем привет.
Для начала вот что надо сделать:
1. Выделить чисто утилитарные классы, которые сами по себе с зависимостями не работают и всё нужное явно декларируют в API, через свойства / параметры.
Этот слой вы скорее всего захотите тестировать и заморачиваться с "вспомни, какие зависимости забыл положить" вам вряд ли понравится.
2. Выделить штуки, которые вы хотите предоставлять в виде зависимостей, по возможности оформить их в виде интерфейсов (разумеется, без фанатизма).
3. Внедрить immutable класс-контекст, который будет отвечать за передачу / подмену зависимостей. Что-то очень легковесное, типа
ServiceContainer.
ВАЖНО: Никогда, ни при каких обстоятельствах не повторяйте
вот эту ошибку в дизайне (метод по умолчанию возвращает null, если сервис не найден). Довелось поработать на проекте с таким решением, если коротко — выстреливало постоянно.
Методы, которые в случае "нунишмогла" возвращают null, надо обзывать с префиксом Try. Иначе ловить вам null reference в самых внезапных местах до конца жизни проекта.
4. Задокументировать типовые сервисы в виде extension-методов. Т.е. большинство вызовов должны выглядеть как
context.GetLogger(), а не как
context.GetService<ILogger>(). Без этого различить "используем стандартное API" от "протаскиваем экзотичную фигню" невозможно и код превращается в мешанинуиз зависимостей.
5. Для свежего фреймворка (читай, для 4.6): рассмотрите возможность передавать контекст неявно, через AsyncLocal<T>. Упрощает передачу контекста до
var logger = Context.CurrentContext.Logger(); // Context - static class
а с using static — до
var logger = CurrentContext.Logger();
без необходимости протаскивать контекст через параметры.
Вот после того как всё это сделано, большинство проблем с зависимостями рассосётся и оставшееся можно будет обсуждать предметно. Конкретно:
LW>Происходит аутентификация пользователя. Теперь лог пишется уже в каталог этого горемычного юзера.
В момент аутентификации происходит подмена контекста, в новом контексте переопределяется логгер.
LW>Юзер выполняет некоторую команду, лог пишется всё в ту же папку, но уже в файл с именем выполняемой команды.
Снова подмена контекста.
Оффтоп: Вас саппорт случаем не убивает за необходимость собирать лог из десятка файлов?
LW>Команда начинает параллелиться и работает с разными компьютерами в сети. Каждая задача начинает писать лог в файл с именем упомянутой выше команды + имя компьютера.
Нувыпоняли
Хотя по-хорошему для конкретно этой задачи нужно не использовать один логгер, а добавлять отдельный для каждого класса задач.
LW>Некоторое время душу терзают мысли о Dependeny Injection. Но в компании уже был неудачный опыт внедрения этой штуки (о котором(ой) я ни сном, ни духом), закончившийся выпиливанием оной с большим количеством матюгов.
DI — это уже нашлёпка поверх протаскиваемого контекста. Если с ним бардак, то DI только замаскирует проблему, а не поможет её вылечить.