Skip to content

InstanceWrapper

reference
2 min readUpdated

Kind: Class

Source: packages/core/injector/instance-wrapper.ts

Part of: Core

InstanceWrapper is the internal dependency-injection record for a provider, storing its token, metatype, scope, and resolved instances. It manages provider instances per request context or transient inquirer, while also retaining constructor and property dependency metadata used during resolution.

Methods

MethodSignatureReturns
getInstanceByContextIdgetInstanceByContextId(contextId: ContextId, inquirerId: string)InstancePerContext<T>
getInstanceByInquirerIdgetInstanceByInquirerId(contextId: ContextId, inquirerId: string)InstancePerContext<T>
setInstanceByContextIdsetInstanceByContextId(contextId: ContextId, value: InstancePerContext<T>, inquirerId: string)void
setInstanceByInquirerIdsetInstanceByInquirerId(contextId: ContextId, inquirerId: string, value: InstancePerContext<T>)void
removeInstanceByContextIdremoveInstanceByContextId(contextId: ContextId, inquirerId: string)void
removeInstanceByInquirerIdremoveInstanceByInquirerId(contextId: ContextId, inquirerId: string)void
addCtorMetadataaddCtorMetadata(index: number, wrapper: InstanceWrapper)void
getCtorMetadatagetCtorMetadata()InstanceWrapper[]
addPropertiesMetadata`addPropertiesMetadata(key: symbolstring, wrapper: InstanceWrapper)`
getPropertiesMetadatagetPropertiesMetadata()PropertyMetadata[]
addEnhancerMetadataaddEnhancerMetadata(wrapper: InstanceWrapper)void
getEnhancersMetadatagetEnhancersMetadata()InstanceWrapper[]
isDependencyTreeDurableisDependencyTreeDurable(lookupRegistry: string[])boolean
introspectDepsAttributeintrospectDepsAttribute(callback: ( collection: InstanceWrapper[], lookupRegistry: string[], ) => boolean, lookupRegistry: string[])boolean
isDependencyTreeStaticisDependencyTreeStatic(lookupRegistry: string[])boolean
cloneStaticInstancecloneStaticInstance(contextId: ContextId)InstancePerContext<T>
cloneTransientInstancecloneTransientInstance(contextId: ContextId, inquirerId: string)InstancePerContext<T>
createPrototypecreatePrototype(contextId: ContextId)void
isInRequestScopeisInRequestScope(contextId: ContextId, inquirer: InstanceWrapper)boolean
isLazyTransient`isLazyTransient(contextId: ContextId, inquirer: InstanceWrapperundefined)`
isExplicitlyRequestedisExplicitlyRequested(contextId: ContextId, inquirer: InstanceWrapper)boolean
isStatic`isStatic(contextId: ContextId, inquirer: InstanceWrapperundefined)`
attachRootInquirerattachRootInquirer(inquirer: InstanceWrapper)void
getRootInquirergetRootInquirer()`InstanceWrapper
getStaticTransientInstancesgetStaticTransientInstances()void
mergeWithmergeWith(provider: Provider)void

Properties

PropertyType
nameany
tokenInjectionToken
asyncboolean
hostModule
isAliasboolean
subtypeEnhancerSubtype
scopeScope
metatype`Type
inject`FactoryProvider['inject']
forwardRefboolean
durableboolean
initTimenumber
settlementSignalSettlementSignal

Where it refuses work

  • InstanceWrapper stops the work with an early return when this.scope === Scope.TRANSIENT && inquirerId, in 3 places.
  • InstanceWrapper stops the work with an early return when !this.isTransient, in 2 places.
  • InstanceWrapper stops the work with an early return when !collection.
  • InstanceWrapper stops the work with an early return when !isUndefined(this.isTreeDurable).
  • InstanceWrapper stops the work with an early return when isStatic.
  • InstanceWrapper stops the work with an early return when lookupRegistry.includes(this[INSTANCE_ID_SYMBOL]).

Diagram

mermaid
graph LR
  Injector[Injector / Resolver] --> Wrapper[InstanceWrapper]
  Wrapper --> Metadata[Constructor & Property Metadata]
  Wrapper --> ContextStore[Context ID Instance Store]
  Wrapper --> TransientStore[Inquirer ID Instance Store]
  ContextStore --> RequestInstance[InstancePerContext]
  TransientStore --> TransientInstance[InstancePerContext]

Usage

ts
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
import { ContextIdFactory } from '@nestjs/core/helpers/context-id-factory';

class LoggerService {
  log(message: string) {
    console.log(message);
  }
}

const loggerWrapper = new InstanceWrapper<LoggerService>({
  token: LoggerService,
  name: LoggerService.name,
  metatype: LoggerService,
});

const contextId = ContextIdFactory.create();

loggerWrapper.setInstanceByContextId(contextId, {
  instance: new LoggerService(),
  isResolved: true,
});

const instanceRecord = loggerWrapper.getInstanceByContextId(contextId);

instanceRecord.instance.log('Resolved from the current context');

// Remove request-scoped data when the context is no longer needed.
loggerWrapper.removeInstanceByContextId(contextId);

AI Coding Instructions

  • Treat InstanceWrapper as DI-container infrastructure; application code should normally consume providers through injection instead of creating wrappers directly.
  • Use getInstanceByContextId() and setInstanceByContextId() for request- or context-specific provider state.
  • For transient providers, preserve the inquirer ID when reading or storing instances so each consumer receives the correct instance.
  • Register constructor dependencies with addCtorMetadata() and property dependencies with addPropertiesMetadata() using the resolved dependency wrappers.
  • Remove context-bound instances after a request or custom context completes to avoid retaining unnecessary scoped instances.

Used by

5 references from 5 files. Each is a place in this repository where the symbol is actually used — go read one rather than trusting an example.

Imported by (5)

  • ExceptionFiltersContextpackages/microservices/context/exception-filters-context.ts:16
  • ListenersControllerpackages/microservices/listeners-controller.ts:45
  • MicroservicesModulepackages/microservices/microservices-module.ts:23
  • TestingInjectorpackages/testing/testing-injector.ts:23
  • SocketModulepackages/websockets/socket-module.ts:27

Was this page helpful?

Download as PDF
InstanceWrapper — NestJS head-to-head