Documentation
Dependency Injection
Scopes

Scopes

Scope defines a life cycle of Providers and InjectionToken. There are two kinds of scopes, Singleton and Operation, former is used by default.

Singleton

As mentioned before, Singleton scope is the default choice in GraphQL Modules. Every Service and Token is created even before the first incoming GraphQL operation and never gets destroyed (only when Node process is terminated).

⚠️

We decided to make it the default choice, because of performance-related reasons. In most cases, there’s no need to instantiate classes on every new request and dispose them later on.

import { Injectable, createModule } from 'graphql-modules'
 
@Injectable()
class Data {}
 
export const myModule = createModule({
  id: 'my-module',
  providers: [Data]
  // ...
})

Operation

All classes and values are created within the context of execution, meaning every incoming GraphQL Operation.

⚠️

Because of performance-related reasons, we recommend using Singletons whenever possible.

The Data class defined below gets instantiated for every new GraphQL operation and disposed once the operation is resolved. Operation Scope doesn’t overlap for incoming requests, so for 3 requests at a time, 3 instances of Data are created, one per each request.

To improve the performance a bit, GraphQL Modules instantiate services on demand. When Data is not called anywhere directly or indirectly by resolvers, the service is not created.

All services and tokens are destroyed right after the GraphQL execution phase.

import { Injectable, Scope, createModule } from 'graphql-modules'
 
@Injectable({
  scope: Scope.Operation // <- here
})
class Data {}
 
export const myModule = createModule({
  id: 'my-module',
  providers: [Data]
  // ...
})

Using Both

Directly accessing a Singleton service in an Operation scoped service is possible, but not the other way around.

With @ExecutionContext decorator, your Singleton services will be able to indirectly access Operation scoped Tokens and Services.