Application 和 Context
Midway 的应用会同时对外暴露不同协议,比如 Http,WebSocket 等等,这里每个协议对 Midway 来说都是由独立的组件提供的。
比如我们前面示例中的 @midwayjs/koa ,就是一个提供 Http 服务的组件,下面我们将以这个组件为例,来介绍内置对象。
每个使用的 Web 框架会提供自己独特的能力,这些独特的能力都会体现在各自的 上下文(Context)和 应用(Application)之上。
定义约定
为了简化使用,所有的暴露协议的组件会导出 上下文(Context)和 应用(Application)定义,我们都保持一致。即 Context 和 Application 。
比如:
import { Application, Context } from '@midwayjs/koa';
import { Application, Context } from '@midwayjs/faas';
import { Application, Context } from '@midwayjs/web';
import { Application, Context } from '@midwayjs/express';
且非 Web 框架,我们也保持了一致。
import { Application, Context } from '@midwayjs/socketio';
import { Application, Context } from '@midwayjs/grpc';
import { Application, Context } from '@midwayjs/rabbitmq';
Application
Application 是某一个组件中的应用对象,在不同的组件中,可能有着不同的实现。Application 对象上会包含一些统一的方法,这些方法统一来自于 IMidwayApplication 定义。
import { Application } from '@midwayjs/koa';
获取方式
在所有被依赖注入容器管理的类中,都可以使用 @MainApp() 装饰器来获取 当前最主要 的 Application,使用 @App('koa') 和参数来获取具名的 Application。
比如:
import { MainApp, App, Controller, Get } from '@midwayjs/core';
import { Application } from '@midwayjs/koa';
@Controller('/')
export class HomeController {
@MainApp()
app: Application;
@App('koa')
koaApp: Application;
@Get('/')
async home() {
// this.app.getConfig()
// this.app.getEnv()
}
}
Main Application
Midway 应用对外暴露的协议是组件带来的,每个组件都会暴露自己协 议对应的 Application 对象。
这就意味着在一个应用中会包含多个 Application,我们默认约定,在 src/configuration.ts 中第一个引入的 Application 即为 Main Application (主要的 Application)。
比如,下面的 koa 中的 Application 实例即为 Main Application (主要的 Application)。
// src/configuration.ts
import { Configuration, ILifeCycle } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as ws from '@midwayjs/ws';
@Configuration({
imports: [koa, ws]
})
export class MainConfiguration implements ILifeCycle {
// ...
}
事实上 Application 都实现与 IMidwayApplication 接口,如果使用通用的 API,没有差别。
成为 Main Application 稍微有一些优势:
- 在大部分的场景下,使用
@App()即可注入获取,无需其他参数 - 优先初始化
比如在多个导出 Application 组件需要加载中间件的情况下,可以简单的编码。
// src/configuration.ts
import { MainApp, App, Configuration, ILifeCycle } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as ws from '@midwayjs/ws';
@Configuration({
imports: [koa, ws]
})
export class MainConfiguration implements ILifeCycle {
@MainApp()
koaApp: koa.Application;
@App('webSocket')
wsApp: ws.Application;
async onReady() {
this.koaApp.useMiddleweare(...);
this.wsApp.useMiddleweare(...);
}
}
非主要的 Application,需要通过 @App() 装饰器的参数或者 ApplicationManager 来获取。
@App() 装饰器的参数为组件的 namespace。
常见的 namespace 如下:
| Package | Namespace |
|---|---|
| @midwayjs/web | egg |
| @midwayjs/koa | koa |
| @midwayjs/express | express |
| @midwayjs/grpc | gRPC |
| @midwayjs/ws | webSocket |
| @midwayjs/socketio | socketIO |
| @midwayjs/faas | faas |
| @midwayjs/kafka | kafka |
| @midwayjs/rabbitmq | rabbitMQ |
| @midwayjs/bull | bull |
| @midwayjs/cron | cron |
getAppDir
用于获取项目根目录路径。
this.app.getAppDir();
// => /my_project
getBaseDir
用于获取项目 TypeScript 基础路径,默认开发中为 src 目录,编译后为 dist 目录。
this.app.getBaseDir();
// => /my_project/src
getEnv
获取当前项目环境。
this.app.getEnv();
// => production
getApplicationContext
获取当前全局依赖注入容器。
this.app.getApplicationContext();
getConfig
获取配置。
// 获取所有配置
this.app.getConfig();
// 获取特定 key 配置
this.app.getConfig('koa');
// 获取多级配置
this.app.getConfig('midwayLoggers.default.dir');