如何利用log4net Unity扩展通过DI解析ILog?含无构造函数场景
解决Unity容器中直接Resolve失败的问题
这个问题我之前在项目里也碰到过,核心原因是你用的Unity-log4net集成包默认只适配了构造函数注入场景——它会在解析带ILog参数的构造函数时,自动为目标类生成对应的log4net实例(比如LogManager.GetLogger(typeof(test))),但并没有在Unity容器中直接注册ILog类型的可解析映射,所以当你直接调用Resolve<ILog>()时,容器不知道该如何创建这个实例。
下面给你两种实用的解决方法:
方法一:注册Logger工厂委托(推荐)
这种方式既保留了log4net按类型生成专属Logger的特性,又能灵活地在任何类中获取Logger:
- 在Unity容器初始化的地方,注册一个
Func<Type, ILog>委托实例:
// 把LogManager.GetLogger方法作为委托注册到容器 DIContainer.Container.RegisterInstance<Func<Type, ILog>>(LogManager.GetLogger);
- 在无构造函数的类中,通过工厂委托获取当前类对应的Logger:
public ILog GetLogger() { // 先解析出工厂委托 var loggerFactory = DIContainer.Container.Resolve<Func<Type, ILog>>(); // 传入当前类的Type,生成对应的Logger return loggerFactory(GetType()); }
方法二:直接注册特定类型的Logger实例
如果你只需要为某个特定类注册Logger(不推荐全局单例,因为log4net的Logger是按类型区分的),可以直接在容器中注册该类对应的Logger:
// 替换成你需要获取Logger的类的Type DIContainer.Container.RegisterInstance<ILog>(LogManager.GetLogger(typeof(YourTargetClass)));
之后调用Resolve<ILog>()就能拿到预先注册的实例,但这种方式不够灵活,每个类都需要单独配置。
另外再确认下:你已经在容器中添加了log4net集成的扩展(比如Container.AddNewExtension<Log4NetExtension>()这类调用),毕竟你已经能正常使用构造注入了,这一步应该是没问题的。
内容的提问来源于stack exchange,提问作者Ali_Nass
相关产品推荐
相关产品推荐

