venkat
venkat

Reputation: 483

How to make availabe a singleton instace to all over the service?

This is how I'm implementing a singleton class

import { AClient } from 'libbrary'
import { Container, Service } from 'typedi';

@Service()
class MyClass {
    private client: AClient;
    
    static getInstance(): MyClass {
        return Container.get(MyClass);
    }
    
    getClient(): AClient {
        if(this.client !== null){
            return this.client;
        }
        this.client = new AClient();
        return this.client;
    }
}

Here the main focus is using Acliet().
And I'm implementing methods of this client in the following way.

class AClientMethodsImplementation {
    async getSomeData() {
        // I need client here so that I can use client.get()
    }
}

Now I should use these methods in my service.

class NeedDataHere {
    // Not only here, in the entire project I need this many places.
    // should I create AClientMethodsImplementation() instance everytime?
    // If that is the case what is the point of a singleton?
    // How to achieve this? What is the correct approach?
}

Am I following the correct approach? Or what is the best way to handle this scenario? I'm saying this is a problem because I observed that hitting getSomeData() by creating new AClientMethodsImplementation class every time is giving the same result even I change input data to that function. I doubt it's caching somewhere.

Upvotes: 1

Views: 1011

Answers (1)

BionicCode
BionicCode

Reputation: 28998

It really depends on your scenario. If AClientMethodsImplementation is meant to be stateless (it will not hold instance related data between method calls) you should declare all of its members static:

class AClientMethodsImplementation {
    static async getSomeData() {
        AClient client = MyClass.getInstance().getClient();
    }
}

class NeedDataHere {
   
   // Call static methods
   let data = AClientMethodsImplementation.getSomeData();
}

If AClientMethodsImplementation is supposed to store instance related data, you would have to create a new instance of course (except the particular method doesn't mutate the instance. In this case it can be static).
If you want this instance to be the same across the application, then you could implement AClientMethodsImplementation as a Singleton.

The preferred alternative to the Singleton pattern is to use Dependency Injection (an implementation of the IoC pattern). This way you can share the same instance, but without sacrificing loose coupling and testability.

Generally you use shared instances (via Dependency Injection or Singleton) when you want to use a single object state in a global scope e.g. a session object like a cookie. Another use case is, where instantiation may be too expensive because of allocation of resources or because instantiation is too time consuming. You then allocate the resources once e.g., a database/service connection and reuse it (shared resources). Another use case is to provide controlled access to a shared resource e.g. a data cache. For example you typically use a shared logger instance across the application.

When checking your code, the benefit of a shared AClient instance could be an increased performance. If you can say the client exposes expensive shared resources or data or is generally too expensive to create multiple instances of it, it's worth to share the instance. The fact that you still create multiple instances of AClientMethodsImplementation does not make the shared instance redundant, obviously.

Upvotes: 2

Related Questions