升级Autofac后log4net.ILog依赖解析失败问题排查
问题分析
FluentMigrator的Migration实例不是由Autofac创建的,而是框架自身实例化的——这就是核心问题。哪怕MigrationService能拿到ILog,那是因为它在Autofac的控制范围内,但单独的Migration类不在容器管理体系中,单元测试直接激活时自然解析不到ILog。
解决步骤
全局注册ILog工厂方法
在Autofac容器配置里,把log4net.ILog注册为动态工厂,让容器能根据目标类型生成对应的ILog实例:builder.Register((ctx, parameters) => { var targetType = parameters.TypedAs<Type>(); return log4net.LogManager.GetLogger(targetType); }).As<log4net.ILog>();之后解析Migration时,传入它的类型参数:
var migration = container.Resolve<FlushRedisOnVersionUpdate>( new TypedParameter(typeof(Type), typeof(FlushRedisOnVersionUpdate)) );让FluentMigrator用Autofac当DI容器
配置MigrationRunner时,指定Autofac作为服务提供者,这样FluentMigrator创建Migration时会从Autofac获取实例,依赖注入自然生效:var autofacProvider = new AutofacServiceProvider(container); var runner = new MigrationRunner( typeof(FlushRedisOnVersionUpdate).Assembly, new MigrationRunnerOptions(), autofacProvider );这样所有Migration实例都归Autofac管理,单元测试里只要初始化好容器,就能直接解析Migration类。
单元测试手动注入ILog
如果单元测试不想依赖完整容器,直接手动创建ILog传入构造函数即可:var log = log4net.LogManager.GetLogger(typeof(FlushRedisOnVersionUpdate)); var migration = new FlushRedisOnVersionUpdate(log);
验证事项
- 确认log4net配置已加载,比如在Startup/Global.asax里调用
log4net.Config.XmlConfigurator.Configure(); - 检查Autofac初始化时,ILog的注册代码确实执行了
- 确保MigrationRunner用的是Autofac的服务提供者,而非默认实现
内容的提问来源于stack exchange,提问作者Dark_Knight
相关产品推荐
相关产品推荐

