VContainer-registering/register-type | 注册——注册纯 C# 类型
1.VContainer 介绍2.VContainer-about/what-is-vcontainer | 概述——VContainer 是什么?3.VContainer-about/what-is-di | 概述——DI 是什么?4.VContainer-getting-started/installation | 入门——安装5.VContainer-getting-started/hello-world | 入门——Hello World6.VContainer-resolving/constructor-injection | 解析——构造函数注入7.VContainer-resolving/method-injection | 解析——方法注入8.VContainer-resolving/property-field-injection | 解析——属性/字段注入9.VContainer-resolving/gameobject-injection | 解析——注入到 MonoBehaviours 中10.VContainer-resolving/container-api | 解析——容器 API
11.VContainer-registering/register-type | 注册——注册纯 C# 类型
12.VContainer-registering/register-using-delegate | 注册——注册使用委托13.VContainer-registering/register-factory | 注册——注册工厂14.VContainer-registering/register-monobehaviour | 注册——注册 MonoBehaviour15.VContainer-registering/register-scriptable-object | 注册——注册 ScriptableObject16.VContainer-registering/register-collection | 注册——注册集合17.VContainer-registering/register-callbacks | 注册——注册回调18.VContainer-integrations/entrypoint | 集成——纯 C# 入口点19.VContainer-integrations/unitask | 集成——Unitask20.VContainer-integrations/unirx | 集成——UniRx21.VContainer-integrations/messagepipe | 集成——MessagePipe22.VContainer-integrations/ecs | 集成——ECS (beta)23.VContainer-scoping/lifetime-overview | 作用域——生命周期管理总览24.VContainer-scoping/generate-child-via-scene | 作用域——通过场景或 prefab 生成子作用域25.VContainer-scoping/generate-child-with-code-first | 作用域——通过代码优先生成子作用域26.VContainer-scoping/project-root-lifetimescope | 作用域——项目根作用域 LifetimeScope27.VContainer-diagnostics/diagnostics-window | 诊断——VContainer 诊断窗口28.VContainer-optimization/source-generator | 优化——源码生成器29.**VContainer-optimization/async-container-build | 优化——异步容器构建30.VContainer-optimization/parallel-container-build | 优化——并行容器构建31.VContainer-optimization/codegen | 优化——预生成 IL 代码(已弃用)32.VContainer-comparing/comparing-to-zenject | 对比 Zenject33.MessagePipe 中文文档有多种方式可以使用 Register
。以以下复杂类型为例:
class ServiceA : IServiceA, IInputPort, IDisposable { /* ... */ }
注册具体类型
builder.Register<ServiceA>(Lifetime.Singleton);
可以这样解析:
class ClassA
{
public ClassA(ServiceA serviceA) { /* ... */ }
}
注册为接口
builder.Register<IServiceA, ServiceA>();
可以这样解析:
class ClassA
{
public ClassA(IServiceA serviceA) { /* ... */ }
}
注册为多个接口
builder.Register<ServiceA>(Lifetime.Singleton)
.As<IServiceA, IInputPort>();
可以这样解析:
class ClassA
{
public ClassA(IServiceA serviceA) { /* ... */ }
}
class ClassB
{
public ClassB(IInputPort inputPort) { /* ... */ }
}
自动注册所有实现的接口
builder.Register<ServiceA>(Lifetime.Singleton)
.AsImplementedInterfaces();
可以这样解析:
class ClassA
{
public ClassA(IServiceA serviceA) { /* ... */ }
}
class ClassB
{
public ClassB(IInputPort inputPort) { /* ... */ }
}
注册所有实现的接口和具体类型
builder.Register<ServiceA>(Lifetime.Singleton)
.AsImplementedInterfaces()
.AsSelf();
可以这样解析:
class ClassA
{
public ClassA(IServiceA serviceA) { /* ... */ }
}
class ClassB
{
public ClassB(IInputPort inputPort) { /* ... */ }
}
class ClassC
{
public ClassC(ServiceA serviceA) { /* ... */ }
}
注册生命周期接口
class GameController : IStartable, ITickable, IDisposable { /* ... */ }
builder.RegisterEntryPoint<GameController>();
:::note
这类似于 Register<GameController>(Lifetime.Singleton).AsImplementedInterfaces()
。与普通接口注册的区别在于它是否在 PlayerLoopSystem
中运行。
:::
如果想自定义入口点的异常处理,可以注册一个回调:
builder.RegisterEntryPointExceptionHandler(ex =>
{
UnityEngine.Debug.LogException(ex);
// 额外的处理 ...
});
如果有多个入口点,可以选择使用以下声明进行分组。
builder.UseEntryPoints(entryPoints =>
{
entryPoints.Add<ScopedEntryPointA>();
entryPoints.Add<ScopedEntryPointB>();
entryPoints.Add<ScopedEntryPointC>().AsSelf();
entryPoints.OnException(ex => ...)
});
这与以下代码相同:
builder.RegisterEntryPoint<ScopedEntryPointA>();
builder.RegisterEntryPoint<ScopedEntryPointB>();
builder.RegisterEntryPoint<ScopedEntryPointC>().AsSelf();
builder.RegisterEntryPointExceptionHandler(ex => ...);
更多信息参阅 纯 C# 入口点 部分。
注册现有实例
// ...
var obj = new ServiceA();
// ...
builder.RegisterInstance(obj);
:::note
RegisterIntance
总是具有 Singleton
生命周期,因此它不存在参数。
:::
可以这样解析:
class ClassA
{
public ClassA(ServiceA serviceA) { /* ... */ }
}
:::note
容器不会管理 RegisterInstance
注册的实例的生命周期。
- 不会自动执行
Dispose
。 - 不会触发方法注入
如果希望容器管理创建的实例,请考虑使用以下替代方案:
将实例注册为接口
使用 As*
声明。
builder.RegisterInstance<IInputPort>(serviceA);
builder.RegisterInstance(serviceA)
.As<IServiceA, IInputPort>();
builder.RegisterInstance(serviceA)
.AsImplementedInterfaces();
参数化注册
如果类型不唯一,可以使用类型指定参数:
builder.Register<SomeService>(Lifetime.Singleton)
.WithParameter<string>("http://example.com");
或使用键名来命名参数:
builder.Register<SomeService>(Lifetime.Singleton)
.WithParameter("url", "http://example.com");
可以这样解析:
class SomeService
{
public SomeService(string url) { /* ... */ }
}
此注册仅在注入到 SomeService
时有效。
class OtherClass
{
// ! 错误
public OtherClass(string hogehoge) { /* ... */ }
}
注册泛型类型
class GenericType<T>
{
// ...
}
builder.Register(typeof(GenericType<>), Lifetime.Singleton);
可以这样解析:
class SomeService
{
public SomeService(GenericType<int> closedGenericType) { /* ... */ }
}
在这种情况下,具体类型在运行时进行构造。Unity 2022.1+ 的 IL2CPP 已支持此动态类型定义,旧版本可能存在兼容性问题。
合集:
VContainer 中文文档
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~