如何在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
相关产品推荐
相关产品推荐

