Разрешить интерфейс из Factory с помощью Autofac - PullRequest
0 голосов
/ 21 июня 2019

Я новичок в Autofac и пытаюсь разрешить интерфейс, используя фабрику, но не могу найти соответствующую часть в документации, чтобы это заработало.

У меня есть следующие интерфейсы для абстрагированияреализация ведения журнала:

public interface ILog
{
    void Info(string message);
    void Debug(string message);
    void Error(string message, Exception exception = null);
}

public interface ILogFactory
{
    ILog GetLogger(Type type);
}

А затем следующие реализации этих интерфейсов:

public class Log : ILog
{
    private readonly Action<string> _logDebug;
    private readonly Action<string, Exception> _logError;
    private readonly Action<string> _logInfo;

    public Log(Action<string> logInfo, Action<string> logDebug, Action<string, Exception> logError)
    {
        _logDebug = logDebug;
        _logInfo = logInfo;
        _logError = logError;
    }
    public void Debug(string message)
    {
        _logInfo(message);
    }

    public void Error(string message, Exception exception = null)
    {
        _logError(message, exception);
    }

    public void Info(string message)
    {
        _logInfo(message);
    }
}

public class Log4NetLogFactory : ILogFactory
{
    public Log4NetLogFactory()
    {
        XmlConfigurator.Configure();
    }

    public ILog GetLogger(Type type)
    {
        var logger = LogManager.GetLogger(type);
        return new Log(logger.Info, logger.Debug, logger.Error);
    }
}

Я застрял с тем, как разрешить ILog в Autofac с использованием ILogFactory.Я зарегистрировал синглтон для ILogFactory с:

builder.RegisterType<Log4NetLogFactory>().As<ILogFactory>().SingleInstance();

, но я не уверен, как разрешить интерфейс ILog, используя метод GetLogger ILogFactory, передавая тип вызывающей стороны.

Itможет показаться, что мне нужно что-то вроде этого:

builder.Register((c, p) => c.Resolve<ILogFactory>().GetLogger(??Caller Type Here??)).As<ILog>();

Но я не уверен, как получить тип вызывающего в конструктор GetLogger.

1 Ответ

0 голосов
/ 25 июня 2019

Мне удалось заставить это работать благодаря этому ответу.Это модуль, с которым я закончил:

public class LoggingModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<Log4NetLogFactory>().As<ILogFactory>().SingleInstance();
        builder.Register((c, p) => c.Resolve<ILogFactory>().GetLogger(p.TypedAs<Type>()));
    }

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing +=
            (sender, args) =>
            {
                var forType = args.Component.Activator.LimitType;

                var logParameter = new ResolvedParameter(
                    (p, c) => p.ParameterType == typeof(ILog),
                    (p, c) => c.Resolve<ILog>(TypedParameter.From(forType)));

                args.Parameters = args.Parameters.Union(new[] { logParameter });
            };
    }

}

Это можно зарегистрировать в контейнере с помощью:

builder.RegisterModule(new LoggingModule());
...