Bor*_*sky 4 .net c# log4net dependency-injection autofac
我使用以下代码为所有需要它的类注册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))
});
}
}
Run Code Online (Sandbox Code Playgroud)
使用autofac的类型扫描注册所有类:
builder.RegisterAssemblyTypes(typeof (IResourceFinder).Assembly)
.AsImplementedInterfaces();
Run Code Online (Sandbox Code Playgroud)
它工作正常!
需要明确注册一个类尝试解决ILog并失败
builder.Register(x => new ClassThatNeedsILog(x.Resolve<ILog>())).AsImplementedInterfaces();
Run Code Online (Sandbox Code Playgroud)
这是上课
public class ClassThatNeedsILog
{
public ClassThatNeedsILog(ILog log)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下异常:
Autofac.Core.Registration.ComponentNotRegisteredException:请求的服务'log4net.ILog'尚未注册.要避免此异常,请注册组件以提供服务,使用IsRegistered()检查服务注册,或使用ResolveOptional()方法解析可选依赖项.
您LogInjectionModule 从不ILog 在容器中注册任何内容只为准备面上的已解析实例提供参数,并且它仅适用于由Autofac创建的实例.
因此,当您编写时,builder.Register(x => new ClassThatNeedsILog(x.Resolve<ILog>()))您正在ClassThatNeedsILog手动创建.同new ClassThatNeedsILog(...)
因此,Autofac不知道你的实例创建(所以你OnComponentPreparing不会运行),因为你没有真正注册任何ILog实现,你得到了ComponentNotRegisteredException.
您有两种选择:
ILog直接在容器中注册ClassThatNeedsILog类型.所以你可以ILog在容器中注册一个:
builder.RegisterInstance(LogManager.GetLogger("Logger")).As<ILog>();
Run Code Online (Sandbox Code Playgroud)
然后你的代码将正常工作.
或者,无论如何你ClassThatNeedsILog手动创建可以直接提供ILog那里:
builder.Register(x => new
ClassThatNeedsILog(LogManager.GetLogger(typeof(ClassThatNeedsILog))))
.AsImplemen??tedInterfaces();
Run Code Online (Sandbox Code Playgroud)
其他选项是让Autofac为您创建实例,因此请将注册更改为:
builder.RegisterType<ClassThatNeedsILog>()
.AsImplemen??tedInterfaces();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Autofac将为您处理实例创建,它将调用OnComponentPreparing模块的方法.
如果要提供其他构造函数参数,可以使用WithParameter和WithParameters方法:
builder.RegisterType<ClassThatNeedsILog>()
.AsImplemen??tedInterfaces()
.WithParameters(new Parameter[] {
ResolvedParameter.ForNamed<IAnotherInterface>("NAME"),
ResolvedParameter.ForNamed<IYetAnotherInterface>("ANOTHERNAME")});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5179 次 |
| 最近记录: |