.NET 6控制台DI报错:StoreCtxFactory服务未注册
问题描述
.NET 6 环境下开发基于依赖注入的控制台应用时,程序启动获取自定义服务实例抛出如下异常:
System.InvalidOperationException: 'No service for type 'ConsoleEfcore.StoreCtxFactory' has been registered.'
已在HostBuilder的ConfigureServices方法中通过services.AddScoped<IStoreFactory, StoreCtxFactory>()完成服务映射,但调用GetRequiredService<StoreCtxFactory>()获取实例时仍触发服务未注册异常,相关代码如下。
相关代码
Program.cs
// See https://aka.ms/new-console-template for more information using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using ConsoleEfcore; using ConsoleEfcore.StoreModels; Console.WriteLine("Hello, World!"); // 从配置文件读取设置 var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false); IConfiguration config = builder.Build(); var Option1 = config.GetSection("TestSettings:Option1"); string Opt = Option1.Value; var SvcBuilder = new HostBuilder() .ConfigureServices((hostContext, services) => { services.AddLogging(configure => configure.AddConsole()) .AddScoped<IStoreFactory, StoreCtxFactory>(); }); var host = SvcBuilder.Build(); DoStuff(host.Services); host.Run(); static void DoStuff(IServiceProvider services) { using IServiceScope serviceScope = services.CreateScope(); IServiceProvider provider = serviceScope.ServiceProvider; StoreCtxFactory store = provider.GetRequiredService<StoreCtxFactory>(); // 测试逻辑 StoreContext ctx = store.GetStoreContext(); int prodCount = ctx.Products.Count(); Console.WriteLine($"We have {prodCount} products"); }
StoreCtxFactory.cs
using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ConsoleEfcore.StoreModels; using Microsoft.EntityFrameworkCore; namespace ConsoleEfcore { public interface IStoreFactory { public StoreContext GetStoreContext() ; } public class StoreCtxFactory : IStoreFactory { private IConfiguration _config; private readonly DbContextOptionsBuilder<StoreContext> _bldr; private StoreContext _ctx; public StoreCtxFactory(IConfiguration config) { _config = config; _bldr = new DbContextOptionsBuilder<StoreContext>(); _bldr.UseSqlServer(_config.GetConnectionString("StoreConn"), sqlOptions => sqlOptions.CommandTimeout(600).EnableRetryOnFailure()); _ctx = new StoreContext(); } public StoreContext GetStoreContext() { StoreContext retval = _ctx; return retval; } } }
问题原因与修复方案
核心报错原因
.NET 内置依赖注入容器按注册时声明的服务类型做映射,当前注册逻辑仅绑定了*接口IStoreFactory到实现类StoreCtxFactory*的映射关系,容器中不会直接暴露具体实现类StoreCtxFactory的解析入口。直接调用GetRequiredService<StoreCtxFactory>()时,容器找不到对应类型的注册条目,就会抛出服务未注册异常。
核心问题修复
两种修复方式二选一即可:
- 推荐方式:按依赖注入最佳实践,依赖抽象而非具体实现,将服务解析代码改为按接口类型获取:
IStoreFactory store = provider.GetRequiredService<IStoreFactory>(); - 若确实需要直接解析具体实现类,在服务注册阶段补充具体类的注册条目:
services.AddScoped<StoreCtxFactory>();
其他隐藏运行时问题
现有代码还存在两个会导致后续运行报错的问题,需要同步修复:
- 手动构建的
IConfiguration实例未注册到DI容器,StoreCtxFactory构造函数依赖IConfiguration参数,容器解析服务时会找不到配置实例。建议直接使用HostBuilder自带的配置构建能力,替换手动构建ConfigurationBuilder的逻辑:var SvcBuilder = new HostBuilder() .ConfigureAppConfiguration((hostCtx, cfg) => { cfg.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false); }) .ConfigureServices((hostContext, services) => { services.AddLogging(configure => configure.AddConsole()) .AddScoped<IStoreFactory, StoreCtxFactory>(); }); StoreCtxFactory构造函数中构建了EF Core的DbContextOptions,但创建StoreContext实例时未传入该配置,EF Core运行时会报未配置数据库提供程序的错误。需要修改_ctx初始化逻辑:_ctx = new StoreContext(_bldr.Options);
内容的提问来源于stack exchange,提问作者bitshift
相关产品推荐
相关产品推荐

