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

.NET Core 7中如何从Startup.ConfigureServices返回IServiceProvider

解决.NET Core 7中IStartup接口ConfigureServices返回IServiceProvider的警告问题

你遇到的警告是因为手动调用services.BuildServiceProvider()会创建一个独立的服务提供程序实例,而框架本身会负责创建全局唯一的实例,这会导致服务实例不一致的潜在问题。正确的实现方式是借助框架提供的IServiceProviderFactory来构建服务提供程序,而不是手动调用Build方法。

修正后的代码实现

首先在Startup类的构造函数中注入IServiceProviderFactory<IServiceCollection>,然后用这个工厂来创建并返回服务提供程序:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication.Cookies;

public class Startup : IStartup
{
    private readonly IConfiguration _configuration;
    private readonly IServiceProviderFactory<IServiceCollection> _serviceProviderFactory;

    public Startup(IConfiguration configuration, IServiceProviderFactory<IServiceCollection> serviceProviderFactory)
    {
        _configuration = configuration;
        _serviceProviderFactory = serviceProviderFactory;
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<SecuWebModulesAuthenticateContext>(options =>
        {
            options
                .UseSqlServer(_configuration.GetConnectionString("DefaultConnection"));
#if DEBUG
            options.LogTo(Console.WriteLine);
#endif
        });

        // 添加认证服务
        services.AddAuthentication()
            .AddCookie("Cookies", options =>
            {
                options.LoginPath = "/Account/Login";
                options.LogoutPath = "/Account/Logout";
                options.AccessDeniedPath = "/Account/AccessDenied";
                options.ReturnUrlParameter = "ReturnUrl";
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = true;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = _configuration["AuthJwt:Issuer"],
                    ValidateAudience = true,
                    ValidAudience = _configuration["AuthJwt:Audience"],
                    ValidateIssuerSigningKey = true,
                    RequireExpirationTime = false,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["AuthJwt:Key"] ?? string.Empty))
                };
            });

        services.AddAuthorization();

        // 使用框架的服务提供程序工厂创建实例,避免重复创建
        return _serviceProviderFactory.CreateServiceProvider(services);
    }

    public void Configure(IApplicationBuilder app)
    {
        // 这里添加你的中间件配置,示例:
        // app.UseHttpsRedirection();
        // app.UseAuthentication();
        // app.UseAuthorization();
        // app.MapControllers();
    }
}

核心原因说明

  • IServiceProviderFactory是框架内置的组件,负责创建全局唯一的服务提供程序实例,避免手动Build导致的重复实例问题。
  • 这种方式完全符合.NET Core的依赖注入设计原则,保证服务的一致性和生命周期管理的正确性。

临时抑制警告的方案(不推荐)

如果你只是想临时隐藏警告(未解决根本问题),可以调用BuildServiceProvider时传入validateScopes: false:

return services.BuildServiceProvider(validateScopes: false);

但此方法仍会创建独立的服务提供程序,可能引发后续服务一致性问题,因此优先推荐使用IServiceProviderFactory的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:37:47