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

ASP.NET Core 6中如何在Program.cs正确调用已注册服务配置其他服务

正确解决依赖注入中用一个服务配置另一个服务的问题

你之前用BuildServiceProvider创建临时服务提供器的方式会触发重复服务警告,原因是这个临时容器和应用最终使用的容器是独立的,会导致服务被实例化两次,同时还可能带来配置不一致、死锁等风险。以下是无需修改第二个服务的正确解决方案:

核心思路

利用依赖注入的延迟解析能力,在注册第二个服务时,通过最终的服务提供器(而非临时容器)解析第一个服务,获取配置所需的值后再实例化第二个服务。

方案1:异步注册(适用于异步获取配置的场景)

如果GetPasswordAsync是异步方法,推荐使用AddSingletonAsync(.NET 6+支持)来处理异步逻辑:

builder.Services.AddFirstService();

// 注册第二个服务时,通过服务提供器解析第一个服务并获取密码
builder.Services.AddSingletonAsync<ISecondService>(async serviceProvider =>
{
    var firstService = serviceProvider.GetRequiredService<IFirstService>();
    var password = await firstService.GetPasswordAsync();
    // 实例化第二个服务,传入获取到的密码
    return new SecondService(password);
});

方案2:同步注册(仅当异步方法可安全同步调用时使用)

如果必须同步处理,可使用GetAwaiter().GetResult(),但要注意避免死锁风险(比如在ASP.NET Core环境中需确保上下文兼容):

builder.Services.AddFirstService();

builder.Services.AddSingleton<ISecondService>(serviceProvider =>
{
    var firstService = serviceProvider.GetRequiredService<IFirstService>();
    var password = firstService.GetPasswordAsync().GetAwaiter().GetResult();
    return new SecondService(password);
});

扩展方法适配(如果AddSecondService是自定义扩展)

如果AddSecondService是你自己写的扩展方法,可以修改它来支持延迟解析(无需修改SecondService类):

public static IServiceCollection AddSecondService(this IServiceCollection services)
{
    services.AddSingletonAsync<ISecondService>(async sp =>
    {
        var firstService = sp.GetRequiredService<IFirstService>();
        var password = await firstService.GetPasswordAsync();
        return new SecondService(password);
    });
    return services;
}

之后直接调用builder.Services.AddSecondService()即可。

为什么原来的方法不可取

  • 创建临时ServiceProvider会导致服务被重复注册和实例化,浪费资源且可能出现状态不一致
  • 临时容器无法感知后续对builder.Services的配置修改,可能导致使用过时的服务配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:45:36