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

.NET6 C#:如何通过工厂方法从依赖注入返回单例MyClass实例

解决方案:在.NET6中通过DI注册并获取不同构造参数的MyClass单例

直接两次调用AddSingleton<MyClass>会导致后一次注册覆盖前一次,因为DI容器中同一类型的注册默认会被后续项覆盖。要实现同时存在两个不同构造参数的MyClass单例,你可以用以下两种原生.NET6方案:

方案一:用包装类区分实例(最直观的原生实现)

通过定义轻量包装类,让DI容器区分不同构造参数的MyClass实例:

  1. 定义包装类
// 包装依赖IMyInterface1的MyClass实例
public class MyClassWithInterface1
{
    public MyClass Instance { get; }
    public MyClassWithInterface1(IMyInterface1 dependency)
    {
        Instance = new MyClass(dependency);
    }
}

// 包装依赖IMyInterface2的MyClass实例
public class MyClassWithInterface2
{
    public MyClass Instance { get; }
    public MyClassWithInterface2(IMyInterface2 dependency)
    {
        Instance = new MyClass(dependency);
    }
}
  1. 注册包装类为单例
    在Program.cs中注册这两个包装类,它们内部的MyClass会自动成为单例:
builder.Services.AddSingleton<MyClassWithInterface1>();
builder.Services.AddSingleton<MyClassWithInterface2>();
  1. 修改工厂类
    注入包装类并直接取出内部的MyClass单例:
public class MyClassFactory
{
    private readonly MyClass _instanceWithInterface1;
    private readonly MyClass _instanceWithInterface2;

    public MyClassFactory(MyClassWithInterface1 wrapper1, MyClassWithInterface2 wrapper2)
    {
        _instanceWithInterface1 = wrapper1.Instance;
        _instanceWithInterface2 = wrapper2.Instance;
    }

    public MyClass GetMyClass(bool condition)
    {
        return condition ? _instanceWithInterface1 : _instanceWithInterface2;
    }
}
  1. 确保工厂类为单例
builder.Services.AddSingleton<MyClassFactory>();

方案二:用字典存储命名实例(更灵活的方式)

直接在DI中注册一个包含两个MyClass单例的字典,通过键名区分:

  1. 注册字典单例
    在Program.cs中创建并注册包含两个实例的字典:
builder.Services.AddSingleton<IDictionary<string, MyClass>>(sp =>
{
    return new Dictionary<string, MyClass>
    {
        ["Interface1"] = new MyClass(sp.GetRequiredService<IMyInterface1>()),
        ["Interface2"] = new MyClass(sp.GetRequiredService<IMyInterface2>())
    };
});
  1. 修改工厂类
    注入字典并根据条件返回对应实例:
public class MyClassFactory
{
    private readonly IDictionary<string, MyClass> _myClassInstances;

    public MyClassFactory(IDictionary<string, MyClass> myClassInstances)
    {
        _myClassInstances = myClassInstances;
    }

    public MyClass GetMyClass(bool condition)
    {
        return condition ? _myClassInstances["Interface1"] : _myClassInstances["Interface2"];
    }
}

关键说明

  • 无论哪种方案,工厂类都是单例,注入到作用域服务后,每次调用GetMyClass返回的都是预先创建好的MyClass单例,不会随作用域服务重建而新建。
  • 若后续升级到.NET7+,可以使用原生键控服务(Keyed Services),写法会更简洁,但.NET6不支持该特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:32:54