gpt4 book ai didi

c# - 与日志注入(inject)模块一起使用时在 Autofac 中显式解析 ILog

转载 作者:太空狗 更新时间:2023-10-30 00:25:01 24 4
gpt4 key购买 nike

我使用以下代码为所有需要它的类注册 log4net。

public class LogInjectionModule : Module
{
private readonly string _configPath;

public LogInjectionModule(string configPath)
{
_configPath = configPath;
}

protected override void AttachToComponentRegistration(IComponentRegistry registry,
IComponentRegistration registration)
{
XmlConfigurator.Configure(new FileInfo(_configPath));

registration.Preparing += OnComponentPreparing;
}

private static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[]
{
new ResolvedParameter((p, i) => p.ParameterType == typeof (ILog),
(p, i) => LogManager.GetLogger(t))
});
}
}

所有类都使用 autofac 的类型扫描注册:

builder.RegisterAssemblyTypes(typeof (IResourceFinder).Assembly)
.AsImplementedInterfaces();

而且效果很好!

需要注册一个类,显式尝试解析 ILog 并失败

builder.Register(x => new ClassThatNeedsILog(x.Resolve<ILog>())).AsImplementedInterfaces();

这是那个类

public class ClassThatNeedsILog
{
public ClassThatNeedsILog(ILog log)
{

}
}

我遇到以下异常:

Autofac.Core.Registration.ComponentNotRegisteredException : The requested service 'log4net.ILog' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

最佳答案

你的 LogInjectionModule 从不注册任何ILog 到容器中只为准备面上的已解析实例提供参数,并且它仅适用于由 Autofac 创建的实例。

所以当你写builder.Register(x => new ClassThatNeedsILog(x.Resolve<ILog>()))您正在创建 ClassThatNeedsILog手动。与 new ClassThatNeedsILog(...)

因此 Autofac 不知道您的实例创建(所以您的 OnComponentPreparing 不会运行)并且因为您还没有真正注册任何 ILog实现你得到 ComponentNotRegisteredException .

你有两个选择:

  • 注册ILog直接在容器中
  • 让 Autofac 创建您的 ClassThatNeedsILog类型。

所以你可以注册一个ILog在容器中:

builder.RegisterInstance(LogManager.GetLogger("Logger")).As<ILog>();

那么你的代码就可以正常工作了。

或者如果您无论如何创建 ClassThatNeedsILog手工可以直接供应ILog那里:

 builder.Register(x => new 
ClassThatNeedsILog(LogManager.GetLogger(typeof(ClassThatNeedsILog))))
.AsImplemen‌​tedInterfaces();

其他选项是让 Autofac 为您创建实例,因此将您的注册更改为:

 builder.RegisterType<ClassThatNeedsILog>()
.AsImplemen‌​tedInterfaces();

在这种情况下,Autofac 将为您处理实例创建,并将调用 OnComponentPreparing模块的方法。

如果你想供应additional constructor parameters你可以使用 WithParameterWithParameters方法:

 builder.RegisterType<ClassThatNeedsILog>()
.AsImplemen‌​tedInterfaces()
.WithParameters(new Parameter[] {
ResolvedParameter.ForNamed<IAnotherInterface>("NAME"),
ResolvedParameter.ForNamed<IYetAnotherInterface>("ANOTHERNAME")});

关于c# - 与日志注入(inject)模块一起使用时在 Autofac 中显式解析 ILog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19778170/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com