VContainer-registering/register-type | 注册——注册纯 C# 类型
有多种方式可以使用 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 已支持此动态类型定义,旧版本可能存在兼容性问题。

浙公网安备 33010602011771号