将全局引用传递给beego控制器

huangapple go评论79阅读模式
英文:

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

huangapple
  • 本文由 发表于 2017年8月1日 17:56:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/45434675.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定