体系化问题
目录
仓储 服务 容器 控制反转 依赖注入之间的关联
一、总览
控制反转(IoC)是思想
依赖注入(DI)是实现 IoC 的手段
容器是实现 DI 的工具
服务是被管理的对象
仓储(Repository)是服务的一种经典形态
二、先从“最抽象”的开始:控制反转(IoC)
什么是控制反转?
谁来创建对象?谁来决定依赖?
传统方式(没有 IoC)
public class OrderService
{
private readonly SqlOrderRepository _repo = new SqlOrderRepository();
}特点:
- OrderService 控制了一切
- 自己
new - 强耦合
- 难测试、难替换
控制反转(IoC)
public class OrderService
{
private readonly IOrderRepository _repo;
public OrderService(IOrderRepository repo)
{
_repo = repo;
}
}👉 OrderService 不再“控制”依赖的创建
👉 控制权被“反转”给了外部
📌 IoC 是一种设计思想,不是技术
三、依赖注入(DI):IoC 的具体实现方式
什么是依赖注入?
把对象所依赖的东西“注入”进来,而不是自己创建
常见 DI 方式
构造函数注入OrderService(IRepo repo)
属性注入[Inject] public IRepo Repo { get; set; }
方法注入void Init(IRepo repo)
📌 DI = IoC 的实现手段之一(也是最主流的)
四、容器(DI Container):DI 的自动化工具
为什么需要容器?
没有容器你也可以 DI:
var repo = new SqlOrderRepository();
var service = new OrderService(repo);但一旦:
- 项目大
- 依赖多
- 生命周期复杂
- WPF / Web 自动创建对象
人肉 new 不现实
容器的职责
管理对象的创建、生命周期和依赖关系
builder.RegisterType<SqlOrderRepository>().As<IOrderRepository>();
builder.RegisterType<OrderService>();容器做的事:
- 保存 interface → 实现类
- 递归创建依赖
- 控制生命周期(单例 / 瞬时)
- 自动注入
容器 ≠ IoC 本身
容器是 IoC + DI 的实现工具
五、服务(Service):业务能力的承载者
什么是服务?
提供“业务行为”的对象
public class OrderService
{
public void PlaceOrder() { }
}特点:
- 表达“做什么”
- 协调多个对象
- 通常是无 UI、无状态或轻状态
常见服务类型
- Application Service(应用服务)
- Domain Service(领域服务)
- Infrastructure Service(基础设施服务)
六、仓储(Repository):一种特殊的服务
仓储是干嘛的?
封装数据访问逻辑,让业务不关心数据来源
public interface IOrderRepository
{
Order GetById(int id);
}实现:
public class SqlOrderRepository : IOrderRepository
{
}仓储的核心价值
- 隔离 ORM / SQL / API
- 可替换(Mock / InMemory)
- 业务只关心“对象”
仓储 ≠ 数据库
仓储是基础设施层的服务
七、层级图
┌─────────────────────────┐
│ 控制反转 IoC │ ← 思想 / 原则
└────────────▲────────────┘
│
通过“依赖注入 DI”
│
┌────────────┴────────────┐
│ DI 容器 Container │ ← 工具
└────────────▲────────────┘
│
管理 / 创建 / 注入
│
┌────────────┴────────────┐
│ 服务 Service │ ← 业务能力
│ (包含 Repository) │
└─────────────────────────┘八、WPF / MVVM 场景
ViewModel
public class OrderViewModel
{
public OrderViewModel(OrderService service) { }
}Service
public class OrderService
{
public OrderService(IOrderRepository repo) { }
}Repository
public class SqlOrderRepository : IOrderRepository { }容器注册
builder.RegisterType<SqlOrderRepository>().As<IOrderRepository>();
builder.RegisterType<OrderService>();
builder.RegisterType<OrderViewModel>();ViewModel 不知道
- SQL
- ORM
- new
- 生命周期
控制权全部在容器
九、最容易混淆但必须记住的 3 句话
- IoC 是“不要自己 new”
- DI 是“别人把依赖给你”
- 容器是“帮你自动干这件事的机器”
十、判断标准
当你写代码时,可以自问:
如果我把某个实现类换掉,需要改几行代码?
- 改很多地方 → IoC 失败
- 只改注册 → 架构健康