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

如何在ASP.NET Core C#中自定义ServiceCollectionExtension并传入依赖参数

解决方案

1. 修正扩展方法,让容器自动解析依赖

当前扩展方法的核心问题是提前手动实例化FdmMediator,但此时仓储等依赖尚未完成注册,且强制调用方传入参数,完全违背了DI容器的设计逻辑。正确做法是让容器在实例化阶段自动解析所有依赖:

方式一:直接注册单例类型(最简实现)

如果FdmMediator的构造函数参数(ILogger、IApplicationTraceRepository、IOptions<GlobalSettings>)都能被容器提供,可直接注册类型:

public static class FdmMediatorBuilderExtensions
{
    public static IServiceCollection AddFdmMediator(this IServiceCollection services)
    {
        // 容器会自动解析构造函数的所有依赖,注册为单例
        services.AddSingleton<FdmMediator>();
        return services;
    }
}

方式二:使用工厂委托(自定义实例化逻辑时用)

如果需要自定义实例化过程(比如手动指定Logger名称),可通过IServiceProvider从容器中按需获取依赖:

public static class FdmMediatorBuilderExtensions
{
    public static IServiceCollection AddFdmMediator(this IServiceCollection services)
    {
        services.AddSingleton<FdmMediator>(sp => 
        {
            // 从容器中获取所需依赖实例
            var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
            var logger = loggerFactory.CreateLogger(nameof(FdmMediator));
            var errorRepo = sp.GetRequiredService<IApplicationTraceRepository>();
            var settings = sp.GetRequiredService<IOptions<GlobalSettings>>();
            
            return new FdmMediator(logger, errorRepo, settings);
        });
        return services;
    }
}

2. Serilog集成下的ILoggerFactory获取

你已经通过builder.Logging.AddSerilog()将Serilog集成到ASP.NET Core日志系统中,此时容器会自动注册Serilog实现的ILoggerFactory,无需额外配置。无论用上述哪种扩展方法,都能从容器中正确获取到该实例。

3. 调整注册顺序(可读性优化)

虽然工厂委托模式不依赖注册顺序,但为了代码逻辑清晰,建议将仓储注册放在AddFdmMediator之前:

// 应用配置
builder.Services.Configure<GlobalSettings>(builder.Configuration.GetSection("ApplicationSettings"));

// 先注册仓储依赖
builder.Services.AddTransient<IApplicationTraceRepository, ApplicationTraceRepository>();

// 再注册FdmMediator
builder.Services.AddFdmMediator();

4. 优化FdmMediator构造函数(可选)

ASP.NET Core DI支持直接注入ILogger<FdmMediator>,比手动通过ILoggerFactory创建更简洁,建议修改构造函数:

public class FdmMediator
{
    private readonly ILogger<FdmMediator> _logger;
    private readonly IApplicationTraceRepository _errorRepository;
    private readonly GlobalSettings _settings;

    public FdmMediator(ILogger<FdmMediator> logger, 
                       IApplicationTraceRepository errorRepository, 
                       IOptions<GlobalSettings> settings)
    {
        _logger = logger;
        _errorRepository = errorRepository;
        _settings = settings.Value;
    }
}

此时直接使用方式一的简单注册即可,容器会自动注入带类型标识的Logger实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:31:22