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

.Net Core依赖注入:如何通过不同工厂方法获取不同实例

如何根据需求调用不同的静态工厂方法获取IMyService实例?

看起来你现在的问题是注册了单一的IMyService实例,但需要根据不同场景调用First.Factory()或Second.Factory()来获取不同配置的实例。这里有几种实用的解决方案,适配不同的.NET版本和需求:

首先先明确你的原始代码结构(方便对照):

public static class First 
{ 
    public static IMyService Factory() 
    { 
        return new MyServiceImplementation() { /* 用Configs配置 */ }; 
    } 
} 

public static class Second 
{ 
    public static IMyService Factory() 
    { 
        return new MyServiceImplementation() { /* 用不同的Configs配置 */ }; 
    } 
}

// 你当前的注册方式
services.AddSingleton(mb => { 
    var myService= First.Factory(); 
    return myService; 
});

方法1:使用.NET 6+的键控服务(Keyed Services)

如果你的项目基于.NET 6或更高版本,键控服务是最直接的方案——它允许你为同一服务类型的不同实例指定唯一标识(键),后续获取时通过键来区分:

注册服务

// 注册第一个配置的实例,标记键为"FirstConfig"
services.AddKeyedSingleton<IMyService>("FirstConfig", (sp, key) => First.Factory());
// 注册第二个配置的实例,标记键为"SecondConfig"
services.AddKeyedSingleton<IMyService>("SecondConfig", (sp, key) => Second.Factory());

获取实例

在需要使用的地方,通过[FromKeyedServices]特性注入指定键的实例:

public class MyServiceConsumer
{
    // 注入第一个配置的实例
    private readonly IMyService _firstConfigService;
    // 注入第二个配置的实例
    private readonly IMyService _secondConfigService;

    public MyServiceConsumer(
        [FromKeyedServices("FirstConfig")] IMyService firstConfigService,
        [FromKeyedServices("SecondConfig")] IMyService secondConfigService)
    {
        _firstConfigService = firstConfigService;
        _secondConfigService = secondConfigService;
    }

    public void UseServices()
    {
        _firstConfigService.DoSomething(); // 使用First工厂的配置
        _secondConfigService.DoSomething(); // 使用Second工厂的配置
    }
}

或者直接从服务提供者获取:

var firstService = serviceProvider.GetRequiredKeyedService<IMyService>("FirstConfig");

方法2:使用工厂委托(兼容旧版.NET)

如果你的项目是.NET 5或更早版本,可以注册一个Func<>委托来封装工厂选择逻辑,这样就能在运行时指定要使用哪个静态工厂:

第一步:定义类型标识(可选,也可以用字符串)

public enum MyServiceConfigType
{
    First,
    Second
}

注册工厂委托

services.AddSingleton<Func<MyServiceConfigType, IMyService>>(sp => configType =>
{
    return configType switch
    {
        MyServiceConfigType.First => First.Factory(),
        MyServiceConfigType.Second => Second.Factory(),
        _ => throw new ArgumentOutOfRangeException(nameof(configType), "不支持的服务配置类型")
    };
});

使用工厂获取实例

在消费类中注入这个委托,按需调用:

public class MyServiceConsumer
{
    private readonly Func<MyServiceConfigType, IMyService> _serviceFactory;

    public MyServiceConsumer(Func<MyServiceConfigType, IMyService> serviceFactory)
    {
        _serviceFactory = serviceFactory;
    }

    public void HandleDifferentScenarios()
    {
        // 场景1:使用First工厂的配置
        var firstService = _serviceFactory(MyServiceConfigType.First);
        firstService.DoWork();

        // 场景2:使用Second工厂的配置
        var secondService = _serviceFactory(MyServiceConfigType.Second);
        secondService.DoWork();
    }
}

方法3:注册独立的命名实例(手动区分)

如果你不想用键控服务或委托,也可以将两个实例注册为命名实例,通过IServiceProvider手动获取:

// 注册第一个实例
services.AddSingleton("FirstService", First.Factory());
// 注册第二个实例
services.AddSingleton("SecondService", Second.Factory());

获取时:

var firstService = (IMyService)serviceProvider.GetService(typeof(IMyService), "FirstService");
var secondService = (IMyService)serviceProvider.GetService(typeof(IMyService), "SecondService");

不过这种方式需要手动类型转换,不如前两种优雅。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:26:47