目录

体系化问题

仓储 服务 容器 控制反转 依赖注入之间的关联

一、总览

控制反转(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 失败
  • 只改注册 → 架构健康