Skip to content

生命周期

InferDI 提供三种生命周期:

种类创建时机缓存于由容器释放
singleton每个拥有它的容器创建一次拥有它的容器
scoped每个子作用域创建一次子作用域
transient每次解析都创建从不缓存

请从 createScope() 返回的子容器解析 scoped 键。默认的检查契约会拒绝从根容器解析这些键。

生命周期规则

单例不能直接依赖 scopedtransient 服务。单例只创建一次并在每个请求间共享,因此如果它捕获了一个作用域级的值——当前请求的上下文、用户或事务——那么这一个请求的状态就会悄无声息地泄漏到所有其他请求中。InferDI 让这种边界情况在类型系统中无法被表达出来,而不是把它留给代码评审。

ts
import { 
Container
} from '@inferdi/inferdi'
class
RequestContext
{
readonly
requestId
= 'req-1'
} class
UserService
{
constructor(readonly
request
:
RequestContext
) {}
} new
Container
()
.
registerClass
('request',
RequestContext
, [], 'scoped')
.
registerClass
('users',
UserService
, ['request'], 'singleton')

无论选择哪种运行时契约,TypeScript 都会拒绝该注册。在默认的检查契约下,如果类型转换绕过了类型系统,运行时也会拒绝同样的形态。

声明的作用域输入属于 scoped 依赖。读取请求、认证上下文、租户或任务载荷的服务应注册为 scopedtransient;编译器会在运行前拒绝 singleton 消费方。参见作用域输入

运行时是否执行这些检查取决于容器契约。默认契约与 fast 契约的准确行为见 容器选项