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

.NET API项目单机器启动失败:依赖注入解析异常排查

问题背景

我有一个基于.NET Framework/.NET Core的API项目,只需在appsettings.json中更新证书本地路径即可运行。项目在多台Windows 10/11机器上都能正常启动,但在某一台本地机器上启动时抛出以下错误:

---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: FSTProj.FSTClinModule.Domain.MedProfileDomain.IMedProfileDomain Lifetime: Scoped ImplementationType: FSTProj.FSTClinModule.Domain.MedProfileDomain.MedProfileDomain': Unable to resolve service for type 'FSTProj.FSTClinModule.Core.IFstUserResolverService' while attempting to activate 'FSTProj.FSTClinModule.Domain.MedProfileDomain.MedProfileDomain'.

相关代码与结构

Startup.cs 的 ConfigureServices 方法

using FSTProj.FSTClinModule.Core;
using FSTProj.FSTClinModule.Domain.MedProfileDomain;
using FSTProj.FSTClinModule.Infrastructure.Common;

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddDBContext<DBContextVariable>();
    AddDependencies(services);
    DomainDependencies(services);

    var contentRoot = Configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
    var certPath = Path.Combine(contentRoot, Configuration["Certificate:Name"]);
    var signingCertificate = new X509Certificate2(certPath, Configuration["Certificate:Password"]);

    services.AddAuthenticationServices(Configuration, signingCertificate);
    services.AddDataProtectionServices(Configuration, signingCertificate);
    //services.AddAuthorizationPolicies<UserPermissionRole>();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "FSTProj.ClinModule.API", Version = "v1" });

        var securityScheme = new OpenApiSecurityScheme
        {
            Name = "JWT Authentication",
            Description = "Enter JWT Bearer token **_only_**",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.Http,
            Scheme = "bearer", // must be lower case
            BearerFormat = "JWT",
            Reference = new OpenApiReference
            {
                Id = JwtBearerDefaults.AuthenticationScheme,
                Type = ReferenceType.SecurityScheme
            }
        };
        c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
        c.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                securityScheme, new string[] { }
            }
        });
    });

    services.AddSingleton<ITelemetryInitializer, HttpContextRequestTelemetryInitializer>();
    services.AddSingleton(c);
    services.AddOptions();
    services.AddTransient<IFstUserResolverService, FstUserResolverService>();
} 

IMedProfileDomain.cs

namespace FSTProj.FSTClinModule.Domain.MedProfileDomain 
{
    public interface IMedProfileDomain
    {
        List<CDMedProfile> GetMedications(int patientid, int vendorid);
        Task<Response> AddMedication(MedProfileActionRequest request);
        Task<MedicationList> GetMedication(MedicationListCommand command);
    }
}

MedProfileDomain.cs

using FSTProj.FSTClinModule.Core;
using FSTProj.FSTClinModule.Core.DbEntities.FST;
using FSTProj.FSTClinModule.Core.DbEntities.FSTClinModule;
using Microsoft.EntityFrameworkCore;

namespace FSTProj.FSTClinModule.Domain.MedProfileDomain
{
    public class MedProfileDomain : IMedProfileDomain
    {
        private FSTClinModuleDBContext _FSTClinModuleDBContext { get; set; }
        public IConfiguration _configuration { get; }
        private FSTDBContext _FSTDBContext { get; set; }
        private readonly IFstUserResolverService _fstUserResolverService;

        public MedProfileDomain(FSTClinModuleDBContext FSTClinModuleDBContext, FSTDBContext FSTDBContext, IConfiguration configuration, IFstUserResolverService fstUserResolverService)
        {
            _FSTClinModuleDBContext = FSTClinModuleDBContext;
            _FSTDBContext = FSTDBContext;
            _configuration = configuration;
            _fstUserResolverService = fstUserResolverService;
        }

        // 其余方法和属性已注释
    }
}

IFstUserResolverService.cs

namespace FSTProj.FSTClinModule.Core
{
#pragma warning disable SA1600 // Elements should be documented
    public interface IFstUserResolverService
    {
        int GetPayerId();
        int GetUserId();
    }
#pragma warning restore SA1600 // Elements should be documented
}

FstUserResolverService.cs

namespace FSTProj.FSTClinModule.Infrastructure.Common
{
    public class FstUserResolverService: IFstUserResolverService
    {
        private readonly IHttpContextAccessor _httpContext;

        public FstUserResolverService(IHttpContextAccessor httpContext)
        {
            _httpContext = httpContext;
        }

        public int GetPayerId(){ }

        public int GetUserId() { }
    }
}

更新信息

更新1:项目文件夹结构

FSTProj.sln
|
├── FSTProj.FSTClinModule.Domain
│   ├── Domain
│   ├── IDomain
│   └── MedProfileDomain
│       └── MedProfileDomain.cs
|
├── FSTProj.FSTClinModule.Infrastructure
|   ├── Common
|   └── FstUserResolverService.cs
|
└── FSTProj.FSTClinModule.Core
    ├── DbEntities
    ├── Enumns
    ├── Model
    └── IFstUserResolverService.cs

更新2:完整堆栈跟踪

---&gt; System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: FSTProj.FSTClinModule.Domain.MedProfileDomain.IMedProfileDomain Lifetime: Scoped ImplementationType: FSTProj.FSTClinModule.Domain.MedProfileDomain.MedProfileDomain': Unable to resolve service for type 'FSTProj.FSTClinModule.Core.IFstUserResolverService' while attempting to activate 'FSTProj.FSTClinModule.Domain.MedProfileDomain.MedProfileDomain'.

问题

该API项目仅在这台特定机器上启动失败的可能原因是什么?同时希望得到可行的解决方案。


解决方案

可能原因分析

  1. DI注册顺序问题:DomainDependencies(services)注册了IMedProfileDomain,但IFstUserResolverService的注册在该方法之后。部分机器可能因缓存不触发校验,但特定机器的DI容器严格按顺序执行,导致注册IMedProfileDomain时依赖的服务尚未注册。
  2. 项目编译不完整:该机器上的Infrastructure项目未正确编译生成,或API项目未正确引用该项目,导致DI找不到IFstUserResolverService的实现类。
  3. 配置/环境异常:该机器上的证书路径错误、文件缺失或权限不足,导致证书加载失败,触发DI容器的连锁校验错误;或WebHostDefaults.ContentRootKey对应的环境变量值异常,导致内容根目录错误。
  4. NuGet包版本不一致:该机器上的Microsoft.Extensions.DependencyInjection系列包版本与其他机器不同,DI容器的校验逻辑存在差异。

可行解决方案

  1. 调整DI注册顺序:将IFstUserResolverService的注册移到DomainDependencies(services)之前,确保依赖服务先于被依赖服务注册:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddDBContext<DBContextVariable>();
        AddDependencies(services);
        // 提前注册依赖服务
        services.AddTransient<IFstUserResolverService, FstUserResolverService>();
        DomainDependencies(services);
        
        // 其余代码保持不变
    }
    
  2. 清理并重新编译项目:
    • 删除项目的bin和obj文件夹
    • 执行dotnet clean和dotnet restore命令
    • 重新编译整个解决方案
  3. 检查配置与环境:
    • 验证appsettings.json中的证书路径是否正确,证书文件是否存在且有读取权限
    • 检查WebHostDefaults.ContentRootKey对应的环境变量值,确保内容根目录指向正确的项目路径
  4. 统一NuGet包版本:对比正常机器的NuGet包版本,将该机器上的Microsoft.Extensions.DependencyInjection系列包更新至相同版本
  5. 注册IHttpContextAccessor:FstUserResolverService依赖IHttpContextAccessor,需显式添加注册:
    services.AddHttpContextAccessor();
    
    放在AddTransient<IFstUserResolverService, FstUserResolverService>()之前。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:17:05