Мне интересно узнать больше о том, как люди вводят в журнал с помощью платформ инъекций зависимостей. Хотя ссылки ниже и мои примеры относятся к log4net и Unity, я не обязательно буду использовать их. Для инъекций зависимостей/IOC я, вероятно, буду использовать MEF, поскольку это стандарт, на котором останавливается остальная часть проекта (большая).Зависимость впрыска и названные регистраторы
Я очень новичок в инъекции зависимостей/ioc и довольно новичок в C# и .NET (написал очень небольшой производственный код в C# /. NET через 10 лет или около того VC6 и VB6). Я провел много исследований по различным решениям для ведения журналов, которые есть там, поэтому я считаю, что у меня есть приличная ручка для их наборов функций. Я просто недостаточно знаком с реальной механикой получения одной зависимой инъекции (или, может быть, более «правильной»), получая абстрагированную версию одной введенной зависимости).
Я видел другие должности, связанные с регистрации и/или инъекции зависимостей, как: dependency injection and logging interfaces
What would a Log4Net Wrapper class look like?
again about log4net and Unity IOC config
Мой вопрос не имеет конкретно делать с " Как я могу внедрить платформу регистрации xxx с помощью инструмента ioc yyy? " Скорее, меня интересует, как люди обрабатывали завершение платформы регистрации (как часто, но не всегда рекомендуется) и конфигурации (то есть app.config). Например, используя log4net в качестве примера, я могу настроить (в app.config) ряд лесозаготовителей, а затем получить эти регистраторы (без инъекции зависимостей) стандартным способом использования кода, как это:
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
В качестве альтернативы , если мой регистратор не названные по имени класса, а скорее, для функциональной области, я мог бы сделать это:
private static readonly ILog logger = LogManager.GetLogger("Login");
private static readonly ILog logger = LogManager.GetLogger("Query");
private static readonly ILog logger = LogManager.GetLogger("Report");
Таким образом, я предполагаю, что мое «требование» было бы что-то вроде этого:
Я хотел бы изолировать источник моего продукта от прямой зависимости от платформы регистрации.
Я хотел был бы иметь возможность разрешить конкретный экземпляр именованного регистратора (возможно, один и тот же экземпляр среди всех запрашивающих экземпляров одного и того же именованного экземпляра) прямо или косвенно с помощью какой-либо инъекции зависимостей, возможно, MEF.
Я не знаю, буду ли я называть это жестким требованием, но я бы хотел, чтобы по желанию вы получили именованный логгер (отличный от регистратора классов). Например, я могу создать регистратор для моего класса на основе имени класса, но один метод требует особой тяжелой диагностики, которую я бы хотел контролировать отдельно. Другими словами, мне может потребоваться, чтобы один класс «зависел» от двух отдельных экземпляров журнала.
Давайте начнем с номером 1. Я прочитал ряд статей, в первую очередь здесь, на StackOverflow, о том, является ли это хорошая идея, чтобы обернуть. См. Ссылку «Лучшие практики» выше и перейдите к комментарию jeffrey hantin для одного представления о том, почему плохо переносить log4net. Если вы сделали обертку (и если бы вы могли обернуть ее эффективно), вы бы привязались строго для цели инъекции/удаления прямой зависимости? Или вы также попытаетесь отвлечь часть или всю информацию о log4net app.config?
Предположим, что я хочу использовать System.Diagnostics, я бы, вероятно, захотел реализовать логический интерфейс на основе интерфейса (возможно, даже используя «общий» интерфейс ILogger/ILog), возможно, на основе TraceSource, чтобы я мог его вводить , Не могли бы вы реализовать интерфейс, скажем, через TraceSource, и просто использовать информацию о приложении.config System.Diagnostics как есть?
Что-то вроде этого:
public class MyLogger : ILogger
{
private TraceSource ts;
public MyLogger(string name)
{
ts = new TraceSource(name);
}
public void ILogger.Log(string msg)
{
ts.TraceEvent(msg);
}
}
И использовать его как это:
private static readonly ILogger logger = new MyLogger("stackoverflow");
logger.Info("Hello world!")
Переходя к числу 2 ... Как разрешить конкретный экземпляр с именем регистратора? Должен ли я просто использовать информацию app.config для платформы регистрации, которую я выбираю (т. Е. Разрешить регистраторы на основе схемы именования в app.config)? Итак, в случае log4net, возможно, я предпочитаю «вводить» LogManager (обратите внимание, что я знаю, что это невозможно, поскольку это статический объект)? Я мог бы обернуть LogManager (назовите его MyLogManager), дать ему интерфейс ILogManager, а затем разрешить интерфейс MyLogManager.ILogManager. Мои другие объекты могут иметь зависимость (Import in MEF parlance) от ILogManager (Экспорт из сборки, где она реализована). Теперь я мог бы иметь объекты, как это:
public class MyClass
{
private ILogger logger;
public MyClass([Import(typeof(ILogManager))] logManager)
{
logger = logManager.GetLogger("MyClass");
}
}
Каждый раз, когда ILogManager называется, он будет непосредственно делегировать LogManager Log4Net в. В качестве альтернативы, может ли обернутый LogManager взять экземпляры ILogger, которые он получает, на основе app.config и добавить их в контейнер (??) MEF по имени. Позже, когда запрашивается логгер с тем же именем, для этого имени запрашивается обернутый LogManager. Если там находится ILogger, это разрешается именно так. Если это возможно с помощью MEF, есть ли какие-либо выгоды?
В этом случае, действительно, ILogManager «вводится», и он может выдавать экземпляры ILogger так, как это обычно делает log4net. Как этот тип инъекций (по существу, на заводе) сравнивается с инъекцией названных экземпляров журнала? Это позволяет более легко использовать файл app.config для log4net (или другой платформы регистрации).
Я знаю, что я могу получить именованные экземпляры из MEF контейнера, как это:
var container = new CompositionContainer(<catalogs and other stuff>);
ILogger logger = container.GetExportedValue<ILogger>("ThisLogger");
Но как я могу получить именованные экземпляры в контейнер? Я знаю об основанной на атрибутах модели, где у меня могут быть разные реализации ILogger, каждый из которых называется (через атрибут MEF), но это на самом деле не помогает мне. Есть ли способ создать что-то вроде app.config (или раздела в нем), который будет перечислять регистраторы (все одинаковые реализации) по имени и что MEF может читать? Может ли/должен быть центральный «менеджер» (например, MyLogManager), который разрешает имена журналов через базовый app.config, а затем вставляет разрешенный регистратор в контейнер MEF? Таким образом, он будет доступен кому-то другому, имеющему доступ к одному и тому же контейнеру MEF (хотя без знания MyLogManager о том, как использовать информацию app.config из log4net, кажется, что контейнер не сможет напрямую разрешить любые именованные журналы).
Это уже довольно долгое время. Надеюсь, это будет согласованным. Не стесняйтесь делиться какой-либо конкретной информацией о том, как вы зависите, внедряете платформу регистрации (мы, скорее всего, рассматриваем log4net, NLog или что-то (надеюсь, тонкое), основанное на System.Diagnostics) в вашем приложении.
Вы вводили «менеджер» и возвращали ли он экземпляры журнала?
Добавили ли вы свою собственную конфигурационную информацию в свой собственный раздел конфигурации или в конфигурационный раздел вашей DI-платформы, чтобы сделать это проще или возможно напрямую вставлять экземпляры регистратора (т. Е. Устанавливать зависимости на ILogger, а не ILogManager).
Что касается статического или глобального контейнера, который имеет в нем интерфейс ILogManager или набор именованных экземпляров ILogger. Таким образом, вместо того, чтобы вводить в обычном смысле (через конструктор, свойство или данные участника), зависимость от протоколирования явно разрешается по требованию. Это хороший или плохой способ инъекции зависимости.
Я отмечаю это как сообщество wiki, так как это не похоже на вопрос с определенным ответом. Если кто-то чувствует себя иначе, не стесняйтесь его менять.
Спасибо за помощь!
Похоже, что MEF и Unity (IoC из группы образцов и практики MS) похожи на сравнение яблок и апельсинов. Возможно, настоящий контейнер IoC - это то, что необходимо для этой конкретной проблемы, которая бы добавила точки расширяемости для добавления пользовательского разрешения зависимостей. http://stackoverflow.com/questions/293051/is-mef-a-dependency-injection-framework –