midwayjs / midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
https://www.midwayjs.org/
MIT License
7.34k stars 573 forks source link

[RFC] about autoload class #203

Closed czy88840616 closed 3 years ago

czy88840616 commented 5 years ago

在有些时候,希望某个类能够被在应用之前被加载一次,比如读取一些配置,同步一些数据等等。由于在 IoC 的体系中,类只有在请求到才会被实例化,不管是请求作用域还是单例,都无法被提前执行。

在现有的方案中,碰到这个情况,我们往往会在 app.ts 中做一些比较简陋的操作。

export = (app) => {
  app.beforeStart(async () => {
    await app.applicationContext.getAsync('syncDBManager');
    await app.applicationContext.getAsync('initRedisManager');
    await app.applicationContext.getAsync('getConfigManager');
  });
}

我们希望有一些更优雅的写法,同时也减少对原来的 app.ts/agent.ts 文件的依赖。

这些类可以放在一个公有的目录下,比如 autoload 什么的。

// 这个类肯定是单例
@provide()
@autoload()
export class SyncDBManager {

  @inject()
  xxxService;  // 注入的必须为单例

  @init()
  sync() {
    // TODO
  }
}

在应用启动时,将会自动加载包含 @autoload 装饰器的类,自动被初始化,自动调用 @init 修饰的方法。

czy88840616 commented 5 years ago

有其他思路可以补充。

atzcl commented 5 years ago

可以不限目录吧,反正启动的时候,都会进行扫描操作的,在扫描的时候就可以知道那一个类是需要自动加载的了 ( 被 @autoload 装饰了)

czy88840616 commented 5 years ago

@atzcl 是的,不限目录,只是举个例子。

kurten commented 3 years ago

https://www.yuque.com/midwayjs/midway_v2/lifecycle