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

能否将同一依赖注入多个同类型对象?当前DI实现是否正确?

代码存在的问题及DI设置的错误

一、编译级错误

  • ListOfFoo类中fooRepository是readonly字段,却在LoadList方法内直接赋值,C#中readonly字段仅能在构造函数或字段初始化时赋值,这会导致编译失败。
  • ListOfFoo的fooList声明为List<A>,但实际添加的是Foo实例,类型不匹配,编译报错。
  • Foo类的构造函数是private修饰,但ListOfFoo中直接实例化Foo,除非两者是嵌套类,否则无法访问私有构造函数,编译报错。
  • Foo构造函数内将参数_repo赋值给未声明的repo变量,实际私有字段是_repo,这里存在笔误,会导致_repo未初始化,后续调用GetEndTimeFromDataBase时触发空引用异常。
  • Foo的GetEndTimeFromDataBase方法缺少闭合的},语法错误。

二、DI设置的核心错误

当前代码完全没有实现依赖注入的核心思想,问题在于:

  • ListOfFoo没有通过依赖注入获取IFooRepository,而是在LoadList方法内手动new FooRepository(DataBase.Main),这依然是紧耦合,无法替换IFooRepository的实现(比如测试用的Mock实现),失去了DI的意义。
  • Foo虽然在构造函数接收IFooRepository,但因为ListOfFoo是自己实例化FooRepository,整个依赖链还是硬编码的,没有利用DI容器管理依赖生命周期和实例化。

三、正确的DI实现方式

1. 修正ListOfFoo,通过构造函数注入依赖

class ListOfFoo
{
    public List<Foo> fooList;
    private readonly IFooRepository _fooRepository;
    public int id;

    // 构造函数注入IFooRepository
    public ListOfFoo(IFooRepository fooRepository)
    {
        _fooRepository = fooRepository;
    }

    public void LoadList()
    {
        fooList = new List<Foo>();
        var results = {...some db calls and logic...};
        foreach (var res in results)
        {
            fooList.Add(new Foo(id, res.StartTime, _fooRepository));
        }
    }
}

2. 修正Foo类的语法问题

class Foo
{
    private readonly IFooRepository _repo;
    public int id;
    public DateTime startTime;

    // 改为public构造函数
    public Foo(int _id, DateTime _startTime, IFooRepository _repo)
    {
        this._repo = _repo;
        id = _id;
        startTime = _startTime;
    }

    private DateTime GetEndTimeFromDataBase()
    {
        return _repo.LoadEndTime(id, startTime);
    }
}

3. 由DI容器管理依赖

在应用启动时,注册依赖关系(以微软DI容器为例):

var services = new ServiceCollection();
// 注册抽象与实现的映射
services.AddScoped<IFooRepository, FooRepository>();
// 注册ListOfFoo,依赖会自动注入
services.AddScoped<ListOfFoo>();
// 为FooRepository注入DataBase.Main
services.AddScoped(provider => new FooRepository(DataBase.Main));

var serviceProvider = services.BuildServiceProvider();
// 获取ListOfFoo实例,依赖已由容器注入
var listOfFoo = serviceProvider.GetRequiredService<ListOfFoo>();

这样做的好处是:

  • 依赖完全解耦,ListOfFoo和Foo都只依赖抽象IFooRepository,不绑定具体实现。
  • 方便单元测试,只需注入Mock的IFooRepository即可,无需连接真实数据库。
  • 依赖的生命周期由DI容器统一管理,避免手动实例化带来的资源管理问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:25:19