使用 Autofac 从 Factory 解析接口
Resolve interface from Factory using Autofac
我是 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);
}
}
我对如何使用 ILogFactory 解析 Autofac 中的 ILog 感到困惑。我已经为 ILogFactory 注册了一个单身人士:
builder.RegisterType<Log4NetLogFactory>().As<ILogFactory>().SingleInstance();
但我不确定如何使用传入调用方类型的 ILogFactory 的 GetLogger 方法解析 ILog 接口。
看来我需要这样的东西:
builder.Register((c, p) => c.Resolve<ILogFactory>().GetLogger(??Caller Type Here??)).As<ILog>();
但我不确定如何将调用者类型输入到 GetLogger 构造函数中。
由于 this 的回答,我成功地完成了这项工作。这是我最终得到的模块:
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());
我是 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);
}
}
我对如何使用 ILogFactory 解析 Autofac 中的 ILog 感到困惑。我已经为 ILogFactory 注册了一个单身人士:
builder.RegisterType<Log4NetLogFactory>().As<ILogFactory>().SingleInstance();
但我不确定如何使用传入调用方类型的 ILogFactory 的 GetLogger 方法解析 ILog 接口。
看来我需要这样的东西:
builder.Register((c, p) => c.Resolve<ILogFactory>().GetLogger(??Caller Type Here??)).As<ILog>();
但我不确定如何将调用者类型输入到 GetLogger 构造函数中。
由于 this 的回答,我成功地完成了这项工作。这是我最终得到的模块:
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());