工作单元与仓储模式依赖注入:主程序DI实现正确性咨询
Hey there! Let's break this down clearly for you:
首先,你的当前写法并不是依赖注入——它只是普通的面向接口实例化,和DI(依赖注入)的核心思想还有本质区别。
先搞懂依赖注入的核心
依赖注入的关键是:让依赖的实例由外部提供,而不是在需要它的代码内部自行创建。这样做的目的是降低代码耦合度,方便后续替换实现、做单元测试,或者统一管理依赖的生命周期。
正确的依赖注入实现方式
1. 手动实现依赖注入(无容器,适合简单场景)
假设你有一个需要用到IOperations的业务类(比如Calculator),正确的做法是把IOperations通过构造函数传给它,而不是让Calculator自己去new实现类:
public class Calculator { private readonly IOperations _operations; // 构造注入:依赖由外部传入,而非内部创建 public Calculator(IOperations operations) { _operations = operations ?? throw new ArgumentNullException(nameof(operations)); } public int GetProduct(int a, int b) { return _operations.Mul(a, b); } }
然后在Main方法中,你需要先创建依赖实例,再把它注入到需要的类中:
static void Main(string[] args) { // 1. 统一创建依赖实例(这一步可以放在项目的配置入口) IOperations ops = new Operations(); // 2. 将依赖注入到Calculator中 Calculator calc = new Calculator(ops); // 3. 使用业务功能 int result = calc.GetProduct(3, 2); Console.WriteLine(result); // 输出6 }
2. 使用.NET内置DI容器(适合实际项目)
如果是复杂度较高的项目,推荐用DI容器来统一管理所有依赖关系,比如.NET自带的IServiceCollection:
首先需要安装Microsoft.Extensions.DependencyInjection NuGet包,然后编写代码:
using Microsoft.Extensions.DependencyInjection; static void Main(string[] args) { // 构建服务容器,注册所有依赖映射 var services = new ServiceCollection() .AddTransient<IOperations, Operations>() // 告诉容器:需要IOperations时,返回Operations实例 .AddTransient<Calculator>(); // 注册Calculator,容器会自动处理它的依赖 var serviceProvider = services.BuildServiceProvider(); // 从容器中获取Calculator实例,容器会自动注入IOperations依赖 var calc = serviceProvider.GetRequiredService<Calculator>(); int result = calc.GetProduct(3, 2); Console.WriteLine(result); }
为什么你的原写法不是DI?
你原来的代码只是把Operations实例赋值给IOperations变量,本质还是在需要的地方自行new了实现类。如果后续有10个类都需要IOperations,你就得在10个地方重复new Operations()——一旦要替换成别的实现(比如测试用的Mock类),你得修改10处代码,这就是紧耦合的问题,而DI正是用来解决这个痛点的。
内容的提问来源于stack exchange,提问作者user9704250
相关产品推荐
相关产品推荐

