Singleton Design Pattern in NestJS and Typescript.

Singleton Design Pattern in NestJS and Typescript.

Table of contents

The Singleton pattern is a design pattern that restricts the instantiation of a class to a single instance across the application. This is useful when exactly one object is needed to coordinate actions across the application. Let's take a closer look from NestJS and Typescript.

How to use singleton pattern in NestJS

In NestJS, modules act as singletons and their providers are also designed to be singletons as long as they are provided within the same module. If you want only single instance of the class across the application then wrap a service in a one module and reuse it across the application. Also don't forget to export the service from the module and then import it anywhere you need it. If you redeclare the service in a providers array in multiple modules that service will be instantiated multiple times.

@Injectable()
export class SingletonService {
    constructor(){ console.log('service created'); }
}
@Module({
  providers: [SingleonService],
  exports: [SingleonService]
})
export class SingletonModule {}
@Module({
  imports: [SingletonModule],
  providers: []
})
export class ConsumerModule {}

Implementation in TypeScript

In TypeScript, we can implement a Singleton by creating a class with a method that creates a new instance of the class if one doesn't exist. If we'd take database for example - singleton pattern is used to prevent multiple database connections. If connection already exists, then we return the current instance of it.

Here's a basic example:

class DBConnection {
    private static instance: DBConnection;

    private constructor() {
        // Private constructor to prevent instantiation
    }

    public static getInstance(): Singleton {
        if (!DBConnection.instance) {
            DBConnection.instance = new DBConnection();
        }
        return DBConnection.instance;
    }
}

In this example, the DBConnection class has a private static property instance that holds the single instance of the class. The constructor of the class is private, which ensures that the class cannot be instantiated from outside the class. The getInstance method checks if an instance of the class already exists. If it does, it returns that instance. If not, it creates a new instance and returns it.

Usage

To use the DBConnection class, you would call the getInstance method:

const singletonInstance = DBConnection.getInstance();

Every time getInstance is called, the same instance of the DBConnection class is returned.

Conclusion

The Singleton pattern is a powerful tool when a single instance of a class needs to be shared and used by multiple clients. It provides a single point of access to the instance. However, it should be used with care, as it can introduce global state into an application, making the it harder to debug and maintain.