Skip to content

ModuleRef

reference
1 min readUpdated

Kind: Class

Source: packages/core/injector/module-ref.ts

Part of: Core

ModuleRef provides programmatic access to providers registered in the current NestJS module. Use it to retrieve existing singleton providers with get(), resolve request- or transient-scoped providers with resolve(), or instantiate classes dynamically with dependency injection through create().

Extends: AbstractInstanceResolver

Methods

MethodSignatureReturns
get`get(typeOrToken: TypeFunction
get`get(typeOrToken: TypeFunction
get`get(typeOrToken: TypeFunction
get`get(typeOrToken: TypeFunction
resolve`resolve(typeOrToken: TypeFunction
resolve`resolve(typeOrToken: TypeFunction
resolve`resolve(typeOrToken: TypeFunction
resolve`resolve(typeOrToken: TypeFunction
resolve`resolve(typeOrToken: TypeFunction
createcreate(type: Type<T>, contextId: ContextId)Promise<T>
introspect`introspect(token: Typestring
registerRequestByContextIdregisterRequestByContextId(request: T, contextId: ContextId)void
instantiateClassinstantiateClass(type: Type<T>, moduleRef: Module, contextId: ContextId)Promise<T>

Properties

PropertyType
injectorInjector

When something fails

  • ModuleRef handles failure in 1 place: it logs it and continues in all 1.

Diagram

mermaid
graph LR
  Consumer[Service / Controller] --> ModuleRef
  ModuleRef -->|get()| Singleton[Registered singleton provider]
  ModuleRef -->|resolve()| Scoped[Request or transient provider instance]
  ModuleRef -->|create()| Dynamic[New dynamically created class]
  ModuleRef --> Container[Nest dependency injection container]

Usage

ts
import { Injectable } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';

@Injectable()
export class ReportsService {
  constructor(private readonly moduleRef: ModuleRef) {}

  async generateReport() {
    // Retrieve an existing singleton provider.
    const configService = this.moduleRef.get(ConfigService, {
      strict: false,
    });

    // Create or retrieve a scoped provider instance.
    const reportContext = await this.moduleRef.resolve(ReportContextService);

    // Instantiate a class while allowing Nest to inject its dependencies.
    const exporter = await this.moduleRef.create(CsvReportExporter);

    return exporter.export({
      timezone: configService.get('TIMEZONE'),
      context: reportContext,
    });
  }
}

AI Coding Instructions

  • Use get() for providers that are already registered and safe to access as singleton instances.
  • Use resolve() for request-scoped or transient providers; it may create a new instance for the current resolution context.
  • Pass { strict: false } to get() only when intentionally searching providers outside the current module boundary.
  • Use create() when dynamically constructing a class that is not necessarily registered as a provider but still requires dependency injection.
  • Prefer constructor injection for known dependencies; use ModuleRef only when runtime or lazy resolution is required.

How it works

ModuleRef is an abstract DI-container reference type. Each Module registers a resolved instance under the ModuleRef token; that instance is created from a module-specific subclass returned by createModuleReferenceType() and is hosted by that module. [packages/core/injector/module.ts:161-179] The subclass closes over its host Module, so its lookup and resolution operations can apply that module’s ID and context. [packages/core/injector/module.ts:602-641]

The abstract class stores the NestContainer, creates an Injector from the container’s preview, snapshot, and instance-decorator context options, and lazily builds an InstanceLinksHost from the container on first use. [packages/core/injector/module-ref.ts:26-47] InstanceLinksHost snapshots links for every module’s providers, injectables, and controllers when constructed. [packages/core/injector/instance-links-host.ts:17-22][packages/core/injector/instance-links-host.ts:55-68]

Was this page helpful?

Download as PDF
ModuleRef — NestJS head-to-head