From 12f8fbe37fc10472e37477ba63c7ee04557e544b Mon Sep 17 00:00:00 2001 From: BorisBorshevsky Date: Sat, 20 May 2017 02:06:28 +0300 Subject: [PATCH] Allow injecting dependencies to controllers --- router.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/router.go b/router.go index 692e72b0..cf1beceb 100644 --- a/router.go +++ b/router.go @@ -116,6 +116,7 @@ type ControllerInfo struct { handler http.Handler runFunction FilterFunc routerType int + initialize func() ControllerInterface } // ControllerRegister containers registered router rules, controller handlers and filters. @@ -181,6 +182,27 @@ func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingM route.methods = methods route.routerType = routerTypeBeego route.controllerType = t + route.initialize = func() ControllerInterface { + vc := reflect.New(route.controllerType) + execController, ok := vc.Interface().(ControllerInterface) + if !ok { + panic("controller is not ControllerInterface") + } + + elemVal := reflect.ValueOf(c).Elem() + elemType := reflect.TypeOf(c).Elem() + execElem := reflect.ValueOf(execController).Elem() + + numOfFields := elemVal.NumField() + for i := 0; i < numOfFields; i++ { + fieldVal := elemVal.Field(i) + fieldType := elemType.Field(i) + execElem.FieldByName(fieldType.Name).Set(fieldVal) + } + + return execController + } + if len(methods) == 0 { for _, m := range HTTPMETHOD { p.addToRouter(m, pattern, route) @@ -760,14 +782,10 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) // also defined runRouter & runMethod from filter if !isRunnable { //Invoke the request handler - vc := reflect.New(runRouter) - execController, ok := vc.Interface().(ControllerInterface) - if !ok { - panic("controller is not ControllerInterface") - } + var execController ControllerInterface = routerInfo.initialize() //call the controller init function - execController.Init(context, runRouter.Name(), runMethod, vc.Interface()) + execController.Init(context, runRouter.Name(), runMethod, execController) //call prepare function execController.Prepare() @@ -803,6 +821,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) default: if !execController.HandlerFunc(runMethod) { var in []reflect.Value + vc := reflect.ValueOf(execController) method := vc.MethodByName(runMethod) method.Call(in) }