代码已经提交:https://github.com/ddzyan/gateway 我现在的目的是框架实现 router . model , controller 等一些重复部分内容,使 egg 继承使用,请问要怎么处理呢,或者说 framework 可以实现这方面的功能吗
[eggjs/egg]egg 如何继承 framework 的 model、controller、router
回答
这个文档有说,egg 并未加载框架的上述目录,看下 Loader 代码。
即使我采用在 framework 配置文件中,额外在挂上目录。然后在 egg 中的路由中调用 app.baseController.home.index 也无法实现对 controller 的继承是吗, 现在的代码报错无法找到config,是因为我在写 baseController 里面的类的时候没有继承 Controller 吧
customLoader: {
baseController: {
directory: 'app/baseController',
inject: 'app', // or app
loadunit: true, // 是否加载框架和插件目录
// other loads options
},
},
可以采用Loader挂在额外的目录方式,来实现 继承 framework controller 的方法吗? 现在我用的是额外挂个目录,在egg里面还是要写 controller ,只是在 controller 里面调用我额外挂载的目录
有一个方法算是黑魔法吧,可以这样:
- 自定义一个 framework 就叫 myFramework 好了
- 在 myFramework 里面
src/core下面写自己的baseControllerbaseService之类的const egg = require('egg')
class BaseController extends egg.Controller { getUserInfo() { ..... } }
module.exports = BaseController
* 然后在 myFramework 的根目录创建 `app.js`
```javascript
const BaseController = require('./app/core/controller')
const BaseService = require('./app/core/service')
class AppBootHook {
constructor (app) {
this.app = app
}
configWillLoad () {
this.app.coreLogger.info('config will load')
}
configDidLoad () {
this.app.coreLogger.info('config did load')
const app = this.app
// 替换 controller 为你写的 controller
app.coreLogger.info('load base controller')
app.Controller = BaseController
require('egg').Controller = BaseController
app.BaseController = BaseController
require('egg').BaseController = BaseController
// 替换 service 为你写的 service
app.coreLogger.info('load base service')
app.Service = BaseService
require('egg').Service = BaseService
app.BaseService = BaseService
require('egg').BaseService = BaseService
}
}
module.exports = AppBootHook
- 然后你就可以在你的 egg 项目中使用 myFramework,定义 controller 或者 service 的时候直接继承并调用你自定义的方法了:
const { Controller } = require('egg');
class HomeController extends Controller { index() { const userInfo = this.getUserInfo(); .... } }
* 如果要 ts 的话,你还得自己写 d.ts 覆盖
当然,也有麻烦一点的,那就是在 framework 里面覆写 AppWorkerLoader 和 AgentWorkerLoader,然后将 loadController loadService loadRouter 给重新写了,具体可以参考 egg-core/ib/loader/mixin。
不过,我没试过。。。。
baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到
baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到
支持重写实例化controller的地方么?我想用proxy对controller进行一些扩展,但是没有找到相应的API
loadController(opt) {
const { app } = this
super.loadController({
directory: [
path.join(__dirname, '../app/controller'),
path.join(app.config.baseDir, 'app/controller')
],
ignore: 'base*.js',
})
// super.loadController(opt)
}
baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到
支持重写实例化controller的地方么?我想用proxy对controller进行一些扩展,但是没有找到相应的API
在 app.js 里面,把 app.BaseController 替换掉即可。
'use strict';
const path = require('path'); const egg = require('egg'); const Controller = require('./core/base_controller'); const Service = require('./core/base_service');
const EGG_PATH = Symbol.for('egg#eggPath');
class Application extends egg.Application { get [EGG_PATH]() { return path.dirname(__dirname); } }
class Agent extends egg.Agent { get [EGG_PATH]() { return path.dirname(__dirname); } }
module.exports = Object.assign(egg, { Application, Agent, Controller, Service });
@atian25 天猪大佬 如果使用framework的方式替换controller基类 可以吗,我再上层业务里requrie('egg').Controller的时候发现还是BaseContextClass