如何使 Typescript 中的单例跨多个模块工作?
How to make a singleton in Typescript work across multiple modules?
我在打字稿应用程序中有一个数据库 class 我正在使用它设置为单例,如下所示:
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;
}
}
当我使用 import databaseService from "../services/database.service";
将模块导入另一个文件并使用 private database = databaseService.getInstance();
获取实例时,它按预期工作,并创建了一个新实例。在 同一文件 中进一步尝试 getInstance()
然后使用该现有对象。
但是,如果我在另一个文件中执行相同的操作,它会创建数据库对象的另一个新实例。这是一个禁忌,因为它最终会搞乱数据库逻辑的工作方式。
如何将单个对象设置为在整个应用程序中共享?最好不要到处传递对象,但如果必须如此,那就这样吧...
单例 class 是 JavaScript 中的潜在反模式,因为没有继承的 class 实例可以表示为普通对象。
在 class 构造函数中显式实现单例模式在 Node.js 和其他模块化环境中是一种反模式,因为模块已经提供了单例。
可以是:
export class Database {}
export default new Database();
其中导出的 class 可能对可扩展性有用,在 TypeScript 中它是输入所必需的,因为它充当接口。
事实证明,正如 Estus 给出的答案的评论中提到的,这个问题的最终解决方案是仔细检查导入模块的情况。
import databaseService from "../services/Database.service";
和
import databaseService from "../services/database.service";
两者都会导致不同的单例实例,但不会标记为不区分大小写的问题 OS。
一旦所有引用都被更正为使用相同的大小写,问题就解决了,并且只创建了一次数据库对象。
我在打字稿应用程序中有一个数据库 class 我正在使用它设置为单例,如下所示:
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;
}
}
当我使用 import databaseService from "../services/database.service";
将模块导入另一个文件并使用 private database = databaseService.getInstance();
获取实例时,它按预期工作,并创建了一个新实例。在 同一文件 中进一步尝试 getInstance()
然后使用该现有对象。
但是,如果我在另一个文件中执行相同的操作,它会创建数据库对象的另一个新实例。这是一个禁忌,因为它最终会搞乱数据库逻辑的工作方式。
如何将单个对象设置为在整个应用程序中共享?最好不要到处传递对象,但如果必须如此,那就这样吧...
单例 class 是 JavaScript 中的潜在反模式,因为没有继承的 class 实例可以表示为普通对象。
在 class 构造函数中显式实现单例模式在 Node.js 和其他模块化环境中是一种反模式,因为模块已经提供了单例。
可以是:
export class Database {}
export default new Database();
其中导出的 class 可能对可扩展性有用,在 TypeScript 中它是输入所必需的,因为它充当接口。
事实证明,正如 Estus 给出的答案的评论中提到的,这个问题的最终解决方案是仔细检查导入模块的情况。
import databaseService from "../services/Database.service";
和
import databaseService from "../services/database.service";
两者都会导致不同的单例实例,但不会标记为不区分大小写的问题 OS。
一旦所有引用都被更正为使用相同的大小写,问题就解决了,并且只创建了一次数据库对象。