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

如何在Microsoft.Extensions.DependencyInjection中实现Autofac的Lambda注册等效功能?

在ASP.NET Core内置DI中实现Autofac风格的Lambda注册

你尝试的代码无法编译,原因是AddScoped<TService, TImplementation>的泛型参数要求传入具体类型,而非方法调用。ASP.NET Core内置DI提供了接受工厂委托的重载方法,用来实现和Autofac中Register(c => ...)一致的逻辑。

正确实现方式

根据你的场景,有两种常见写法:

1. 无需从DI容器获取其他依赖的情况

直接使用接受Func<IServiceProvider, TService>的AddScoped重载,在委托中调用你的GetCommandContext方法:

services.AddScoped<IAppQuerier, AppQuerier>();  // 标准注册

// 正确写法:使用工厂委托
services.AddScoped<IAppDbContext>(_ => GetCommandContext());

private IAppDbContext GetCommandContext()
{
    // 注意:确保Substitute的类型和返回值匹配(这里应该是IAppDbContext而非ICommandsContext)
    var appDbContext = Substitute.For<IAppDbContext>();
    var roundOccurrences = AppTestsData.GetRoundOccurrences();
    appDbContext.RoundOccurrences.Returns(roundOccurrences);

    return appDbContext;
}

2. 需要从DI容器获取其他服务的情况

如果你的GetCommandContext需要依赖DI中的其他服务,可以修改方法接受IServiceProvider参数,在委托中传入容器实例:

services.AddScoped<IAppQuerier, AppQuerier>();

// 传入IServiceProvider给工厂方法
services.AddScoped<IAppDbContext>(sp => GetCommandContext(sp));

private IAppDbContext GetCommandContext(IServiceProvider sp)
{
    // 从DI容器获取所需依赖
    var someDependency = sp.GetRequiredService<ISomeDependency>();
    
    var appDbContext = Substitute.For<IAppDbContext>();
    var roundOccurrences = AppTestsData.GetRoundOccurrences();
    appDbContext.RoundOccurrences.Returns(roundOccurrences);

    return appDbContext;
}

注意事项

  • 确保GetCommandContext返回的实例类型和IAppDbContext兼容(你原代码中Substitute.For<ICommandsContext>()返回的是ICommandsContext,如果它未实现IAppDbContext,会导致类型转换错误,需修正为Substitute.For<IAppDbContext>())。
  • 委托中的IServiceProvider参数可以用来获取DI容器中注册的其他服务,这和Autofac注册时的c(IComponentContext)作用类似。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:06:17