英文:
Passing a global reference to beego controllers
问题
我正在尝试通过路由将在main.go中初始化的日志记录器引用传递给控制器层,代码如下所示:
main.go
logger, _ := zap.NewProduction()
defer logger.Sync() // 刷新缓冲区(如果有的话)
sugar := logger.Sugar()
routers.Init(sugar)
routers.go
func Init(l *zap.SugaredLogger) {
nsMgt := beego.NewNamespace("/api",
beego.NSNamespace("/account",
beego.NSInclude(
&controllers.AccountController{
Logger: l,
},
),
),
)
)
controller.go
type AccountController struct {
beego.Controller
Logger *zap.SugaredLogger
}
// @Title Get account details.
// @Summary Get account details
// @Param filterKey query string true "possible values 'id' or 'username'"
// @Param filterValue query string true "value of the filter key"
// @Success 200 {object} models.User
// @router / [get]
func (o *AccountController) Get() {
o.Logger.Info("this is cool")
}
它在控制器函数中抛出了空指针错误。有没有办法将全局日志记录器变量传递给控制器层?在主函数中初始化日志记录器很重要,因为它需要延迟关闭。
英文:
I'm trying to pass a logger reference initialised inside main.go to Controller layer via the router like bellow
main.go
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
routers.Init(sugar)
routers.go
func Init(l *zap.SugaredLogger) {
nsMgt := beego.NewNamespace("/api",
beego.NSNamespace("/account",
beego.NSInclude(
&controllers.AccountController{
Logger: l,
},
),
),
)
)
controller.go
type AccountController struct {
beego.Controller
Logger *zap.SugaredLogger
}
// @Title Get account details.
// @Summary Get account details
// @Param filterKey query string true "possible values 'id' or 'username'"
// @Param filterValue query string true "value of the filter key"
// @Success 200 {object} models.User
// @router / [get]
func (o *AccountController) Get() {
o.Logger.Info("this is cool")
}
It throws a null pointer error at the controller function. Is there a way to pass a global logger variable to controller layer?. It's important to initialise the logger at the main function 'cause it requires a defered close.
答案1
得分: 1
Beego使用反射为每个请求创建一个控制器实例,它不使用您传递的实际实例,并且不会将参数传递给新实例。您可以在控制器上定义一个"Prepare"方法,在调用匹配的控制器方法之前,Beego会在运行时调用该方法,在那里您可以通过调用工厂方法或某种IoC容器(不确定这是否是Go的最佳实践)来初始化所需的结构字段(例如服务层)。
我还寻找了在初始化结构时传递依赖项的选项,但目前还不可能。
请查看请求处理逻辑:https://beego.me/docs/mvc/
"Prepare"方法的文档在这里:
https://beego.me/docs/mvc/controller/controller.md
英文:
Beego uses reflection to create a controller instance for each request, it doesn't use the actual instance you pass in and it doesn't passes the params to the new instances. You can define "Prepare" method on your controller which will be called by Beego in runtime before invoking the matched controller method, there you can initialize the required struct fields (e.g. service layer) by calling a factory method or some sort of IoC container (Not sure if this is the best practice for Go)
I also looked for an option to pass dependencies when initializing the struct but it's not possible at the moment.
Take a look on the request handling logic: https://beego.me/docs/mvc/
Prepare method is documented here:
https://beego.me/docs/mvc/controller/controller.md
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论