You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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>();
    

其他隐藏运行时问题

现有代码还存在两个会导致后续运行报错的问题,需要同步修复:

  1. 手动构建的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>();
         });
    
  2. StoreCtxFactory构造函数中构建了EF Core的DbContextOptions,但创建StoreContext实例时未传入该配置,EF Core运行时会报未配置数据库提供程序的错误。需要修改_ctx初始化逻辑:
    _ctx = new StoreContext(_bldr.Options);
    

内容的提问来源于stack exchange,提问作者bitshift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:03:34