模块引用
Nest 提供了ModuleRef
类来导航提供器的内部列表,并使用其注入令牌作为查找键来获取对任何提供器的引用。
ModuleRef
类还提供了一种方法来动态实例化静态和限定作用域的提供器。
ModuleRef
可以通过正常的方式注入到类中:
ModuleRef
类是从@nestjs/core
包导入的。
检索实例¶
ModuleRef
实例(模块引用)有一个get()
方法。
这个方法使用注入令牌/类名来获取存在于 当前 模块中(已被实例化)的提供器、控制器或可注入对象(例如,守卫、拦截器等)。
要从全局上下文中检索提供器(例如,如果提供器已被注入到不同的模块中),将 { strict: false }
选项作为第二个参数传递给 get()
。
解决作用域内的提供器¶
要动态解析作用域的提供器(瞬态或请求作用域),请使用resolve()
方法,并将提供器的注入令牌作为参数传递。
resolve()
方法从它自己的 DI 容器子树 中返回提供器的唯一实例。
每个子树都有一个惟一的上下文 标识符。
因此,如果多次调用该方法并比较实例引用,就会发现它们是不相等的。
要跨多个resolve()
调用生成单个实例,并确保它们共享生成的 DI 容器子树,可以将上下文标识符传递给resolve()
方法。
使用ContextIdFactory
类来生成上下文标识符。
该类提供了一个create()
方法,该方法返回一个适当的惟一标识符。
ContextIdFactory
类是从@nestjs/core
包中导入的。
注册请求的提供器¶
手动生成的上下文标识符(使用ContextIdFactory.create()
)表示 DI 子树,其中REQUEST
提供器是undefined
,因为它们没有被 Nest 依赖注入系统实例化和管理。
要为手动创建的 DI 子树注册一个自定义的REQUEST
对象,请使用ModuleRef#registerRequestByContextId()
方法,如下所示:
获得当前子树¶
有时,您可能希望在 请求 上下文中解析请求作用域的提供器的实例。
假设CatsService
是请求作用域的,您希望解析CatsRepository
实例,该实例也被标记为请求作用域的提供器。
为了共享相同的 DI 容器子树,你必须获取当前的上下文标识符,而不是生成一个新的上下文标识符(例如,使用ContextIdFactory.create()
函数,如上所示)。
要获得当前的上下文标识符,首先使用@Inject()
装饰器注入请求对象。
了解关于请求提供器的更多信息此处.
现在,使用ContextIdFactory
类的getByRequest()
方法创建一个基于请求对象的上下文 id,并将其传递给resolve()
调用:
动态实例化自定义类¶
要动态实例化一个之前没有注册为提供器的类,请使用模块引用的create()
方法。
这种技术使您能够在框架容器之外有条件地实例化不同的类。