I have a Database class in a typescript application I'm using that's set up as a singleton like so:
export default class Database {
private static instance: Database;
//Actual class logic removed
public static getInstance(): Database {
if (!Database.instance) {
Database.instance = new Database();
Database.instance.logger.debug("Creating new Database Instance");
} else {
Database.instance.logger.debug("Using existing Database Instance");
}
return Database.instance;
}
}
When I import the module into another file using import databaseService from "../services/database.service";
and get the instance using private database = databaseService.getInstance();
it works as expected, and creates a new instance. Any further attempts to getInstance()
in the same file then use that existing object.
However, if I then do the same in another file, it creates another new instance of the Database object. This is a no-no as eventually it'll mess up how the database logic works.
How can I get a single object set up to be shared across the entire application? Preferably without passing the object around everywhere, but if that's how it has to be then so be it...
I have a Database class in a typescript application I'm using that's set up as a singleton like so:
export default class Database {
private static instance: Database;
//Actual class logic removed
public static getInstance(): Database {
if (!Database.instance) {
Database.instance = new Database();
Database.instance.logger.debug("Creating new Database Instance");
} else {
Database.instance.logger.debug("Using existing Database Instance");
}
return Database.instance;
}
}
When I import the module into another file using import databaseService from "../services/database.service";
and get the instance using private database = databaseService.getInstance();
it works as expected, and creates a new instance. Any further attempts to getInstance()
in the same file then use that existing object.
However, if I then do the same in another file, it creates another new instance of the Database object. This is a no-no as eventually it'll mess up how the database logic works.
How can I get a single object set up to be shared across the entire application? Preferably without passing the object around everywhere, but if that's how it has to be then so be it...
Share Improve this question asked Mar 24, 2019 at 13:53 KaedekoKaedeko 4825 silver badges14 bronze badges2 Answers
Reset to default 3Singleton classes are potential antipatterns in JavaScript because an instance of a class without inheritance could be expressed as plain object.
Explicit implementation of singleton pattern in class constructor is an antipattern in Node.js and other modular environments because modules already provide singletons.
It can be:
export class Database {}
export default new Database();
Where exported class may be useful for extensibility, in TypeScript it is necessary for typing because it acts as an interface.
As it turns out, the eventual solution to this issue was, as mentioned in the ments of the answer given by Estus, double checking the cases of the imported modules.
import databaseService from "../services/Database.service";
and
import databaseService from "../services/database.service";
both result in different instances of the singleton, but won't flag up as an issue on a case-insensitive OS.
Once all references were corrected to use the same case, the issue was solved and only once Database object was created.