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

咨询Microsoft.Extensions.DependencyInjection实现Lamar风格For/Use注入方法

关于Microsoft.Extensions.DependencyInjection实现类似Lamar的For().Use()功能的疑问

我想咨询用于IoC实现的Microsoft.Extensions.DependencyInjection库:能否在该库中实现类似Lamar库的services.For<TService>().Use<TClient>()功能?我的代码示例如下:

public static void AddSomeServices(this IServiceCollection services, Func<SomeContext> context)
{
    // 类似这样的实现
    services.For<ISomeService>().Use(ctx => context().Extensions.SomeService);
}

请问Microsoft.Extensions.DependencyInjection中是否有此类内置函数?


Microsoft.Extensions.DependencyInjection(以下简称MS DI)没有内置和Lamar的For<TService>().Use<TClient>()完全一致的链式API。不过你可以通过扩展方法自己实现类似语法,或者直接使用MS DI原生注册方式达成相同效果。

原生替代方案

针对你示例中的场景,直接用MS DI的AddSingleton/AddScoped/AddTransient就能实现相同注册逻辑,比如:

public static void AddSomeServices(this IServiceCollection services, Func<SomeContext> context)
{
    // 根据实际需求选择生命周期,这里以Singleton为例
    services.AddSingleton<ISomeService>(_ => context().Extensions.SomeService);
}

如果是注册具体实现类(对应Lamar的Use<SomeServiceImpl>),直接使用:

services.AddScoped<ISomeService, SomeServiceImpl>();

自定义扩展实现类似Lamar的链式语法

如果你偏好Lamar的链式风格,可以自行编写简单的扩展类模拟该语法:

public static class ServiceCollectionExtensions
{
    public static ForBuilder<TService> For<TService>(this IServiceCollection services)
        where TService : class
    {
        return new ForBuilder<TService>(services);
    }
}

public class ForBuilder<TService> where TService : class
{
    private readonly IServiceCollection _services;

    public ForBuilder(IServiceCollection services)
    {
        _services = services;
    }

    public void Use<TImplementation>() where TImplementation : class, TService
    {
        _services.AddTransient<TService, TImplementation>();
        // 可按需添加Scoped、Singleton等生命周期的重载方法
    }

    public void Use(Func<IServiceProvider, TService> implementationFactory)
    {
        _services.AddTransient(implementationFactory);
        // 同样可扩展其他生命周期的重载
    }
}

之后你就能像Lamar那样调用:

services.For<ISomeService>().Use<SomeServiceImpl>();
// 或者带工厂逻辑的版本
services.For<ISomeService>().Use(ctx => context().Extensions.SomeService);

需要注意的是,自定义扩展只是语法糖,底层仍依赖MS DI的原生注册逻辑,不会额外增加功能。如果只是简单注册需求,直接使用原生API更简洁;如果团队习惯Lamar的风格,自定义扩展可以统一代码写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:27:07