4.2 KiB
4.2 KiB
VContainer(Unity DI)文档笔记
来源: https://vcontainer.hadashikick.jp/ 记录时间: 2026-02-11
一句话总结
VContainer 是面向 Unity 的高性能 DI 容器,核心是 LifetimeScope + 明确生命周期 + PlayerLoop EntryPoint,兼顾性能、可维护性与可测试性。
核心概念
LifetimeScope是组合根(Composition Root),在这里集中做注册。- 依赖推荐通过构造函数注入,业务入口可以使用纯 C# 类,不必全部依赖
MonoBehaviour。 - 容器不可变(Immutable),强调线程安全和稳定性。
安装方式
- OpenUPM(推荐)
- 命令:
openupm add jp.hadashikick.vcontainer
- 命令:
- UPM Git URL
"jp.hadashikick.vcontainer": "https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer#1.17.0"
- 手动导入
.unitypackage - 官方要求: Unity 2018.4+
Hello World 最小流程
- 新建继承
LifetimeScope的组件(如GameLifetimeScope)。 - 在
Configure(IContainerBuilder builder)中注册依赖。 - 把该
LifetimeScope挂到场景中的 GameObject。 - 通过构造函数自动注入依赖。
- 需要接入 Unity 生命周期时,使用 marker interface(例如
ITickable)。
生命周期(Lifetime)
Singleton- 全容器共享一个实例。
- 同一容器内同类型不能重复注册。
Transient- 每次
Resolve新建实例。
- 每次
Scoped- 每个
LifetimeScope一份实例。 - 子 Scope 与父 Scope 可以拥有各自实例。
- Scope 销毁时会释放引用并调用已注册对象的
IDisposable。
- 每个
父子 Scope 规则要点:
- 子 Scope 找不到注册时会向父 Scope 查找。
- 父子都注册了同类型时,优先使用“最近的 Scope”。
- 注意:如果仅销毁
LifetimeScope,注册为Lifetime.Scoped的MonoBehaviour不会自动销毁;需要通过层级管理或显式释放策略处理。
常见注册写法
- 注册具体类
builder.Register<ServiceA>(Lifetime.Singleton);
- 以接口注册
builder.Register<IServiceA, ServiceA>();
- 多接口注册
builder.Register<ServiceA>(Lifetime.Singleton).As<IServiceA, IInputPort>();
- 自动注册已实现接口
builder.Register<ServiceA>(Lifetime.Singleton).AsImplementedInterfaces();
- 同时保留接口与自身类型
builder.Register<ServiceA>(Lifetime.Singleton).AsImplementedInterfaces().AsSelf();
- 实例注册
builder.RegisterInstance(obj);- 注意:
RegisterInstance默认等同单例,但实例生命周期不由容器托管(不会自动Dispose、不会自动做方法注入)。
Plain C# EntryPoint(推荐实践)
- 使用
builder.RegisterEntryPoint<T>()把纯 C# 类挂到 VContainer 自己的 PlayerLoop。 - 可用接口与大致时机:
IInitializable/IPostInitializableIStartable/IAsyncStartable/IPostStartableIFixedTickable/IPostFixedTickableITickable/IPostTickableILateTickable/IPostLateTickableIDisposable(随容器释放)
- 未捕获异常可用
RegisterEntryPointExceptionHandler自定义处理。
性能与优化
- 官方定位:相对 Zenject 在 Resolve 路径上更快、GC 更低。
- 默认使用反射;可启用 Source Generator 提升运行时性能。
- Source Generator 要求 Unity 2021.3+;从 v1.13.0 起基于 Roslyn Source Generator。
我的落地建议(Unity 项目)
- 把
LifetimeScope当成“模块边界”,按场景/系统拆分父子 Scope。 - 业务逻辑放纯 C#,
MonoBehaviour尽量薄,只做视图与桥接。 - 高频路径优先构造函数注入,减少运行期反射与临时分配。
- 先统一生命周期约定(Singleton/Scoped/Transient 选择标准),再大规模迁移。
参考页面
- About: https://vcontainer.hadashikick.jp/
- Installation: https://vcontainer.hadashikick.jp/getting-started/installation
- Hello World: https://vcontainer.hadashikick.jp/getting-started/hello-world
- Register Plain C# Type: https://vcontainer.hadashikick.jp/registering/register-type
- Lifetime Overview: https://vcontainer.hadashikick.jp/scoping/lifetime-overview
- Plain C# Entry point: https://vcontainer.hadashikick.jp/integrations/entrypoint
- Source Generator: https://vcontainer.hadashikick.jp/optimization/source-generator