如何定位DryIoC容器注册来源及解决ASP.NET Core类型兼容错误
DryIoC + ASP.NET Core 日志配置类型不匹配异常的解决
错误根源
这个DryIoc.ContainerException是因为DryIoC和ASP.NET Core默认的日志组件注册逻辑不兼容:ConsoleFormatterConfigureOptions<T>是泛型配置类,但MS DI的批量注册在DryIoC中被解析成了错误的绑定,导致ConsoleFormatterConfigureOptions(非泛型)被绑定到了IConfigureOptions<JsonConsoleFormatterOptions>服务类型上,自然出现类型分配失败。
如何定位注册来源
开启DryIoC的注册跟踪,打印冲突注册的详细信息:
var container = new DryIoc.Container().With(trackRegistrations: true); var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(new DryIocServiceProviderFactory(container)); // 在Build前筛选并打印目标注册 foreach (var reg in container.GetServiceRegistrations()) { var serviceName = reg.ServiceType.FullName; if (serviceName != null && serviceName.Contains("JsonConsoleFormatterOptions")) { Console.WriteLine($"服务: {serviceName}\n实现类: {reg.ImplementationType}\n注册信息: {reg.RegistrationInfo}"); } } var app = builder.Build();运行后就能看到这个错误注册是由
Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsole方法自动添加的。直接排查ASP.NET Core默认服务注册:ASP.NET Core在启动时会自动调用
AddConsole注册日志格式化器配置,这就是冲突的源头。
快速解决方法
方案1:启用DryIoC的MS DI兼容规则(最推荐)
创建容器时指定兼容MS DI的规则,让DryIoC正确处理批量泛型注册:
var container = new DryIoc.Container(rules => rules.UseMicrosoftDependencyInjectionRules()); var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(new DryIocServiceProviderFactory(container)); var app = builder.Build();
方案2:手动修正错误注册
如果必须使用自定义容器,先移除错误绑定,再重新注册正确的泛型实现:
var container = new DryIoc.Container(); var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(new DryIocServiceProviderFactory(container)); // 移除错误的单个注册 container.Unregister(typeof(Microsoft.Extensions.Options.IConfigureOptions<Microsoft.Extensions.Logging.Console.JsonConsoleFormatterOptions>)); // 重新注册正确的泛型配置类 container.Register( typeof(Microsoft.Extensions.Options.IConfigureOptions<>), typeof(Microsoft.Extensions.Logging.Console.ConsoleFormatterConfigureOptions<>), Reuse.Singleton); var app = builder.Build();
方案3:使用DryIoC默认创建的容器
放弃手动创建容器,让DryIocServiceProviderFactory自动生成容器,它会默认启用MS DI兼容规则:
var builder = WebApplication.CreateBuilder(args); // 不传入自定义容器,使用Factory默认创建的容器 builder.Host.UseServiceProviderFactory(new DryIocServiceProviderFactory()); var app = builder.Build();
内容的提问来源于stack exchange,提问作者Mathias Rotter
相关产品推荐
相关产品推荐

