如何使Typescript中的单例跨多个模块工作?

时间:2019-03-24 13:53:02

标签: javascript node.js typescript singleton

我正在使用的打字稿应用程序中有一个Database类,它被设置为单例,如下所示:

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()的任何进一步尝试,然后使用该现有对象。

但是,如果我随后在另一个文件中执行相同的操作,它将创建数据库对象的另一个新实例。这是一个禁忌,因为它将最终弄乱数据库逻辑的工作方式。

如何设置要在整个应用程序中共享的单个对象?最好不要在任何地方传递对象,但是如果那是必须的,那就这样吧……

2 个答案:

答案 0 :(得分:1)

单个类是JavaScript中潜在的反模式,因为没有继承的类的实例可以表示为普通对象。

在类构造函数中明确实现单例模式是Node.js和其他模块化环境中的反模式,因为模块已经提供了单例。

可以是:

export class Database {}

export default new Database();

导出的类可能对扩展性有用,在TypeScript中,由于它充当接口,因此有必要进行键入。

答案 1 :(得分:0)

事实证明,如Estus给出的答案的评论所述,最终解决此问题的方法是仔细检查导入模块的情况。

import databaseService from "../services/Database.service";import databaseService from "../services/database.service";都导致不同的单例实例,但是在不区分大小写的OS上不会标记为问题。

将所有引用更正为使用相同的大小写之后,此问题就解决了,并且仅在创建数据库对象之后。