我对 Autofac 和 Nlog 还很陌生,我需要一些帮助来了解我的 Autofac LoggingModule for Nlog 中发生了什么。由于遵循injecting-nlog-with-autofacs-registergeneric ,它按预期工作。但不仅仅是复制粘贴,我想确保我了解每种方法中发生的情况(Load & AttachToComponentRegistration)。如果您可以查看我的想法并进一步澄清我的任何错误(我很确定),我将不胜感激。先感谢您!
- 使用 Nlog 的数据库目标
- 使用 Autofac 进行依赖注入
- 用于学习的 ASP.NET MVC Web 应用程序
- Dvd 库应用程序(DvdAdd、DvdEdit、DvdDelete、DvdList)
记录模块
public class LoggingModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder
.Register((c, p) => new LogService(p.TypedAs<Type>()))
.AsImplementedInterfaces();
}
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 });
};
}
}
我对里面的代码的理解Load()
c - 提供给表达式的参数c是在其中创建组件的组件上下文(一个 IComponentContext 对象)。可以访问服务或解析组件依赖关系的上下文。
p - 带有传入参数集的 IEnumerable
AsImplementedInterfaces - Autofac 允许其用户显式或隐式注册类型。虽然“ As ”用于显式注册,但“ AsImplementedInterfaces ”和“ AsSelf ”用于隐式注册。换句话说,容器会根据它实现的所有接口自动注册实现。
思考: Load方法代码注册一个新的LogService类(代表“ c ”),logger的类型(代表“ p ”)作为LogService类的构造函数参数
问题:
- 我上面的想法正确吗?
- 它应该是 SingleInstance 还是应该/它只会在调用类范围内存在?(我正在考虑我的工作单元)
我对里面的代码的理解AttachToComponentRegistration()
AttachToComponentRegistration方法 - 重写以将特定于模块的功能附加到组件注册。
AttachToComponentRegistration参数:
- IComponentRegistry componentRegistry - 根据它们提供的服务提供组件注册。
- IComponentRegistration注册- 描述容器内的逻辑组件。
registration.Preparing - 需要新实例时触发。通过在提供的事件参数中设置 Instance 属性,可以提供该实例以跳过常规激活器。
var forType = args.Component.Activator.LimitType;
args = Autofac.Core.PreparingEventArgs - 在激活过程之前触发以允许更改参数或提供替代实例。
Component = PreparingEventArgs.Component 属性- 获取提供被激活实例的组件
Activator = IComponentRegistration.Activator 属性 - 获取用于创建实例的激活器。
LimitType = IInstanceActivator.LimitType 属性 - 获取组件实例已知可转换为的最具体类型。
思考- 据我了解forType
,这个变量保存调用类的Name
和FullName
从哪里调用日志服务?
问题:
- 我的想法
forType
正确吗?
var logParameter = new ResolvedParameter(
(p, c) => p.ParameterType == typeof(ILog),
(p, c) => c.Resolve<ILog>(TypedParameter.From(forType)));
ResolvedParameter - 可用作提供从容器中动态检索的值的一种方式,例如通过名称解析服务。
思考logParameter
- 这是我开始迷路的地方。也是如此,它检查参数是否为 ILog 类型,如果是,它将使用构造函数参数解析它并传入forType
变量?
问题:
- 我对
logParameter
上面的想法正确吗?
args.Parameters = args.Parameters.Union(new[] { logParameter });
args.Parameters = PreparingEventArgs.Parameters属性 - 获取或设置提供给激活器的参数。
args.Parameters.Union = 使用默认相等比较器生成两个序列的集合并集。返回一个System.Collections.Generic.IEnumerable`1,其中包含来自两个输入序列的元素,不包括重复项。
关于的想法args.Parameters
-我现在真的不知道,除了猜测它返回一个参数集合并删除重复项?
问题:
- 你能帮我谈谈发生了什么
args.Parameters
吗?
logParameter 调试器图像 Nlog 数据库表图像
日志服务类
public class LogService : ILog
{
private readonly ILogger _log;
public LogService(Type type)
{
_log = LogManager.GetLogger(type.FullName);
}
public void Debug(string message, params object[] args)
{
Log(LogLevel.Debug, message, args);
}
public void Info(string message, params object[] args)
{
Log(LogLevel.Info, message, args);
}
public void Warn(string message, params object[] args)
{
Log(LogLevel.Warn, message, args);
}
public void Error(string message, params object[] args)
{
Log(LogLevel.Error, message, args);
}
public void Error(Exception ex)
{
Log(LogLevel.Error, null, null, ex);
}
public void Error(Exception ex, string message, params object[] args)
{
Log(LogLevel.Error, message, args, ex);
}
public void Fatal(Exception ex, string message, params object[] args)
{
Log(LogLevel.Fatal, message, args, ex);
}
private void Log(LogLevel level, string message, object[] args)
{
_log.Log(typeof(LogService), new LogEventInfo(level, _log.Name, null, message, args));
}
private void Log(LogLevel level, string message, object[] args, Exception ex)
{
_log.Log(typeof(LogService), new LogEventInfo(level, _log.Name, null, message, args, ex));
}
}
日志接口
public interface ILog
{
void Debug(string message, params object[] args);
void Info(string message, params object[] args);
void Warn(string message, params object[] args);
void Error(string message, params object[] args);
void Error(Exception ex);
void Error(Exception ex, string message, params object[] args);
void Fatal(Exception ex, string message, params object[] args);
}