【问题标题】:Globle module without import not working nestjs没有导入的全球模块不起作用nestjs
【发布时间】:2021-12-31 23:06:46
【问题描述】:

我正在尝试在nest.js 中实现一个全局模块

我已经创建了如下所示的服务

export interface ConfigData {
    DB_NAME:        string;
}

@Injectable()
export class ConfigManager {
    private static _instance?: ConfigManager;
    public static configData:ConfigData | null;
    private constructor() {
        console.log(ConfigManager)
        if (ConfigManager._instance)
            ConfigManager._instance = this;
        else{
            ConfigManager._instance = new ConfigManager()
            ConfigManager.configData = <ConfigData|null><unknown>ConfigManager.fetchSecretData()
        }
    }
    private static async fetchSecretData():Promise<ConfigData|null>{
        // some data from db
    }
    // static get instance() {
    //     return ConfigManager._instance ?? (ConfigManager._instance = new ConfigManager());
    //     //return ConfigManager._instance ?? (ConfigManager._instance = ConfigManager.fetchSecretData()) //new ConfigManager());
    // }
    
}

configuration.module.ts

@Global()
@Module({
    providers: [ConfigManager],
    exports: [ConfigManager],
})
export class ConfigurationModule {}

并在 app.module.ts 中添加 ConfigurationModule 导入。

还在服务上添加私有构造函数,无法将其添加到 module.ts 文件中。

我希望我应该能够在任何地方configData 而无需导入 ConfigManager。但它不起作用......

ConfigManager 在没有导入的情况下不可用。

【问题讨论】:

  • 你是如何尝试使用ConfigManager的?
  • 我想像 ConfigManager 一样访问。此类的属性.. 但问题是 ConfigManager 不导入就无法访问
  • 没有像import { ConfigManager } from './config-manager.provider.ts这样的导入?
  • 是的,我喜欢将它添加到全局并且可以像 ConfigManger.someproperty 一样简单地访问
  • 好吧,要分配给全局变量,您只需要执行globals.ConfigManager = ConfigManager。也就是说,我强烈建议不要使用全局变量,因为它们不能提供清晰性并且最终会开始混淆

标签: javascript typescript nestjs


【解决方案1】:

您只用 @Global 装饰器标记了您的模块,但 NestJS 需要以某种方式初始化该模块并使其全局可用。

这意味着您必须将此模块添加到您的核心应用程序模块中,然后 NestJS 将为您完成剩下的工作,所以像这样(或者您的根模块被命名):

@Module({
  imports: [ConfigurationModule],
})
export class AppModule {}

来自documentation

@Global() 装饰器使模块具有全局作用域。全局模块 应该只注册一次,通常由根模块或核心模块注册。

【讨论】:

    【解决方案2】:

    这是 es6/ts 的“按设计”:如果不导入该类,您将无法使用它。

    您将 di(实例化/组合)的概念与导入(定义模块范围内可用的类)混合在一起

    【讨论】:

      【解决方案3】:

      嵌套中的全局模块仅意味着您不必在导入中包含该模块:[] 需要它的提供程序的所有其他模块。全局模块中的提供程序仍然像普通提供程序一样运行,即您需要在需要的地方注入它。

      因此,在您的情况下,由于您已经将 @Global() 添加到 ConfigManager 并在 app.module.ts 中导入了 ConfigurationModule,因此对于任何其他想要使用 @ 的模块,您不需要在导入中添加 ConfigurationModule 987654325@。但是,您仍然需要注入 ConfigManager 提供程序 - 这就是 @Injectable() 的含义:)。

      要进行注入,您需要在需要使用ConfigManager 的类中添加一个constructor(private configManager: ConfigManager) {},并且由于您需要访问类的类型,因此您还需要import { ConfigManager } from '../path/to/ConfigManager'。

      【讨论】:

        猜你喜欢
        • 2020-06-30
        • 1970-01-01
        • 2021-11-06
        • 2020-07-08
        • 2022-12-11
        • 1970-01-01
        • 2022-12-20
        • 2021-09-18
        • 2015-04-30
        相关资源
        最近更新 更多