Asp.Net Core多接口实现服务注入控制器时返回null问题求助
问题原因及解决方案
你遇到的问题核心是:服务容器中仅注册了接口ICheckService到具体实现的映射,但未将DesignerService、CheckerService这些具体类型本身注册到容器中。
当你调用serviceProvider.GetService<DesignerService>()时,容器找不到该具体类型的注册信息,因此返回null。而直接注入ICheckService能正常工作,是因为容器能根据接口映射找到对应的实例。
修正步骤
1. 修改Startup.cs的服务注册逻辑
需要先将具体服务类注册到容器,再配置接口映射或服务解析委托:
public delegate ICheckService ServiceResolver(string key); // 第一步:注册具体服务类型到容器 services.AddScoped<DesignerService>(); services.AddScoped<CheckerService>(); // 第二步(可选):注册接口到实现的映射,用于支持直接注入ICheckService的场景 // 如果不需要直接注入ICheckService,这两行可以省略 services.AddScoped<ICheckService>(sp => sp.GetService<CheckerService>()); // 第三步:注册服务解析委托 services.AddScoped<ServiceResolver>(serviceProvider => key => { return key switch { "DesignerService" => serviceProvider.GetService<DesignerService>(), "CheckerService" => serviceProvider.GetService<CheckerService>(), _ => throw new KeyNotFoundException($"未找到key为'{key}'的服务") }; });
2. 控制器代码保持不变
你的控制器构造函数代码无需修改,保持原来的即可:
private readonly ICheckService _checklistService; public DesignerController(ServiceResolver serviceAccessor) { _checklistService = serviceAccessor("DesignerService"); }
另一种可选方案(无需注册具体服务)
如果不想单独注册具体服务,也可以通过获取所有ICheckService的实现,再根据类型筛选:
services.AddScoped<ICheckService, DesignerService>(); services.AddScoped<ICheckService, CheckerService>(); services.AddScoped<ServiceResolver>(serviceProvider => key => { var allServices = serviceProvider.GetServices<ICheckService>(); return key switch { "DesignerService" => allServices.FirstOrDefault(s => s is DesignerService), "CheckerService" => allServices.FirstOrDefault(s => s is CheckerService), _ => throw new KeyNotFoundException() }; });
这种方式适合服务数量不多的场景,但性能略逊于直接注册具体服务的方式。
内容的提问来源于stack exchange,提问作者AoLiGei
相关产品推荐
相关产品推荐

