VContainer-resolving/container-api | 解析——容器 API
通过 IObjectResolver 可直接访问 DI 容器。VContainer 会自动注册 IObjectResolver 并将其注入到任何需要的地方,因此你可以通过依赖注入获取实例:
例如:
class ClassA
{
public ClassA(IObjectResolver container)
{
// 解析已注册的 ServiceA 实例。
// 如果将子类注册为 ServiceA,这里返回的会是子类实例
var serviceA = container.Resolve<ServiceA>();
// 对 foo 对象执行依赖注入。
// 重复注入同一个对象会覆盖已标记为 [Inject] 的属性、字段或方法。
container.Inject(foo);
// 为当前 GameObject 及其子物体中的所有 MonoBehaviour 执行依赖注入。
// 无论目标 GameObject 和 MonoBehaviours 是否处于启用状态。
container.InjectGameObject(gameObject);
// 实例化预制体并自动注入依赖,
// 依赖项将注入其 MonoBehaviours(及其子对象的 MonoBehaviours)中。
// 通过其他方式创建 GameObject(例如程序化生成或从 Addressables 加载),建议使用 InjectGameObject。
var object1 = container.Instantiate(prefab);
// 支持与 Object.Instantiate 相同的重载方法
var object2 = container.Instantiate(prefab, parent);
var object3 = container.Instantiate(prefab, position, rotation, parent);
}
}
如果经常以某种模式使用 IObjectResolver.Inject,可以考虑为其编写扩展方法。实际上,几乎每个 IObjectResolver API 都是一个扩展方法(包括前面的代码示例)。
:::tip
仅在以下情况显式使用 IObjectResolver.Resolve,其他情况建议优先使用自动注入:
- 其他支持的注入方式不满足需求
- 使用 VContainer 回调时需要暴露
IObjectResolver(例如 构建回调 或 需要容器依赖和运行时参数的工厂函数)
虽然所有解析方式性能相近(如果使用了 IL 生成器),但直接使用 Resolve 会增加代码量且意图不够清晰。
:::
LifetimeScope 通过其 Container 属性持有 IObjectResolver 的引用。VContainer 会自动注册它,但在容器构建后通常不需要频繁使用。
class ClassA
{
public ClassA(LifetimeScope currentScope)
{
// 如果需要,也可以注入 LifetimeScope,
// 但多数情况下直接注入 ServiceA 足矣。
var foo = currentScope.Container.Resolve<ServiceA>();
}
}

浙公网安备 33010602011771号