Используя structuremap с log4net оберткой

У меня есть следующий интерфейс:

public interface ILogger
{
    void Debug(string message, params object[] values);
    void Info(string message, params object[] values);
    void Warn(string message, params object[] values);
    void Error(string message, params object[] values);
    void Fatal(string message, params object[] values);
}

и следующая реализация:

public class Log4netLogger : ILogger
{
    private ILog _log;

    public Log4netLogger(Type type)
    {
        _log = LogManager.GetLogger(type);
    }

    public void Debug(string message, params object[] values)
    {
        _log.DebugFormat(message, values);
    }

    // other logging methods here...

}

Моя идея состояла в том, чтобы использовать structuremap для инстанцирования класса Log4netLogger с использованием Типа класса, который сделал вход. Однако я не могу ни за что в жизни выяснить, как передать тип класса вызова к structuremap так, чтобы он мог быть передан конструктору регистрирующейся реализации. Любой совет относительно того, как сделать это (или лучший путь) больше всего ценился бы.

10
задан Chris 21 December 2009 в 21:57
поделиться

3 ответа

Если типовой параметр является контекстно-зависимым, то я не думаю, что это сработает, как показано на рисунке. Если вам нужно передать что-то специфическое для контекста в конструкторе, то вам, скорее всего, придется создать заводской интерфейс и реализацию, возвращающую экземпляр ILogger:

public interface ILoggerFactory
{
    ILogger Create(Type type);   
}

public class LoggerFactory : ILoggerFactory
{
    public ILogger Create(Type type)
    {
        return new Log4netLogger(type);
    }
}

Возможно, можно загрузить StructureMap для поставки нужного вам экземпляра на основе типа, но это предполагает ограниченное количество заранее известных типов.

.
1
ответ дан 3 December 2019 в 15:52
поделиться

Мне действительно нужно избавиться от привычки отвечать на свой собственный вопрос, но для тех, кто его пересекает, вот ответ.

return ObjectFactory.With(type).GetInstance<T>();

На самом деле, у меня есть обертка для структурного отображения (чтобы не подвергать мое приложение зависимости от структурного отображения), которая выглядит следующим образом:

public static class ServiceManager
{
    public static T Get<T>()
    {
        return ObjectFactory.GetInstance<T>();
    }

    public static T Get<T>(Type type)
    {
        return ObjectFactory.With(type).GetInstance<T>();
    }
}

Всякий раз, когда в коде мне нужен логгер, я вызываю следующий:

ServiceManager.Get<ILogger>(GetType()).Info("Logging page view...");
1
ответ дан 3 December 2019 в 15:52
поделиться

Мы используем подобную ILogger-обертку вокруг log4net и обычно используем впрыск конструктора. Мы используем перехватчик как заводской метод, отвечающий за создание логгера. Вот наш типичный реестр для настройки логов.

public class CommonsRegistry : Registry
{
    public CommonsRegistry()
    {
        For<ILogger>()
            .AlwaysUnique()
            .TheDefault.Is.ConstructedBy(s =>
            {
                if (s.ParentType == null)
                    return new Log4NetLogger(s.BuildStack.Current.ConcreteType);

                return new Log4NetLogger(s.ParentType);
            });

        var applicationPath = Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location);
        var configFile = new FileInfo(Path.Combine(applicationPath, "log4net.config"));
        XmlConfigurator.ConfigureAndWatch(configFile);
    }
}

Проверка нулевого родительского типа необходима, когда есть зависимости от конкретных типов.

Остальное - необязательная настройка log4net.

Одна вещь, которая мне нравится в этой настройке, это возможность использовать нулевой логгер для юнит-тестирования.

25
ответ дан 3 December 2019 в 15:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: