能否将同一依赖注入多个同类型对象?当前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
相关产品推荐
相关产品推荐

