eudore controller

Controller

eudore控制器实现通过分析控制器得到路由方法路径和闭包执行控制器方法。

控制器接口需要实现初始化、释放和注入三个方法,初始化和释放完成控制器对象的初始化和释放过程,注入方法完成注入控制器对应的路由到路由器中。

type Controller interface {
    Init(Context) error
    Release(Context) error
    Inject(Controller, RouterMethod) error
}

ControllerBase

ControllerBase是最基本的控制器实现,Init会初始化ctx,Inject调用ControllerInjectStateful函数实现注入路由。

type ControllerBase struct {
    Context
}


func (base *ControllerBase) Init(ctx Context) error {
    base.Context = ctx
    return nil
}


func (base *ControllerBase) Release(Context) error {
    return nil
}


func (base *ControllerBase) Inject(controller Controller, router RouterMethod) error {
    return ControllerInjectStateful(controller, router)
}


func (base *ControllerBase) ControllerRoute() map[string]string {
    return nil
}

ControllerInjectStateful

ControllerInjectStateful函数有状态控制器的路由注入功能。

实现主要分为四段:

  • 先根据控制器名称或者参数设置Group。

  • 然后创建控制器路由参数函数。

  • 遍历通过控制器类型获得路由方法和路由路径组,生成Router.AddHandler的方法和路径参数。

  • 使用ControllerFuncExtend传递控制器方法习惯参数,交给函数扩展处理。

func ControllerInjectStateful(controller Controller, router Router) error {
    pType := reflect.TypeOf(controller)
    iType := reflect.TypeOf(controller).Elem()

    
    cname := iType.Name()
    cpkg := iType.PkgPath()
    group := router.GetParam("controllergroup")
    if group != "" {
        router = router.SetParam("controllergroup", "").Group("/" + group)
    } else if strings.HasSuffix(cname, "Controller") {
        router = router.Group("/" + strings.ToLower(strings.TrimSuffix(cname, "Controller")))
    } else if strings.HasSuffix(cname, "controller") {
        router = router.Group("/" + strings.ToLower(strings.TrimSuffix(cname, "controller")))
    }

    
    pfn := defaultRouteParam
    v, ok := controller.(controllerRouteParam)
    if ok {
        pfn = v.GetRouteParam
    }

    
    pool := NewControllerPoolSync(controller)
    for method, path := range getRoutesWithName(controller) {
        m, ok := pType.MethodByName(method)
        if !ok || path == "" {
            continue
        }

        router.AddHandler(getRouteMethod(method), path+" "+pfn(cpkg, cname, method), ControllerFuncExtend{
            Controller: controller,
            Name:       fmt.Sprintf("%s.%s.%s", cpkg, cname, method),
            Index:      m.Index,
            Pool:       pool,
        })
    }
    return nil
}

ControllerInjectSingleton






func ControllerInjectSingleton(controller Controller, router Router) error {
    pType := reflect.TypeOf(controller)
    iType := pType.Elem()

    
    cname := iType.Name()
    cpkg := iType.PkgPath()

    switch {
    case router.GetParam("controllergroup") != "":
        group := router.GetParam("controllergroup")
        router = router.SetParam("controllergroup", "").Group("/" + group)
    case strings.HasSuffix(cname, "Controller"):
        router = router.Group("/" + strings.ToLower(strings.TrimSuffix(cname, "Controller")))
    case strings.HasSuffix(cname, "controller"):
        router = router.Group("/" + strings.ToLower(strings.TrimSuffix(cname, "controller")))
    default:
        router = router.Group("")
    }

    enableextend := router.GetParam("enable-route-extend") != ""
    router.SetParam("enable-route-extend", "")
    var fnInit, fnRelease HandlerFunc
    if enableextend {
        fnInit = newControllerSingletionInit(controller, fmt.Sprintf("%s.%s.Init", cpkg, cname))
        fnRelease = newControllerSingletionRelease(controller, fmt.Sprintf("%s.%s.Release", cpkg, cname))
    }

    
    pfn := defaultRouteParam
    v, ok := controller.(controllerRouteParam)
    if ok {
        pfn = v.GetRouteParam
    }

    pool := NewControllerPoolSingleton(controller)
    for method, path := range getRoutesWithName(controller) {
        m, ok := pType.MethodByName(method)
        if !ok || path == "" {
            continue
        }

        if enableextend {
            
            h := reflect.ValueOf(controller).Method(m.Index)
            SetHandlerAliasName(h, fmt.Sprintf("%s.%s.%s", cpkg, cname, method))
            router.AddHandler(getRouteMethod(method), path+" "+pfn(cpkg, cname, method), fnInit, h.Interface(), fnRelease)
        } else {
            
            router.AddHandler(getRouteMethod(method), path+" "+pfn(cpkg, cname, method), ControllerFuncExtend{
                Controller: controller,
                Name:       fmt.Sprintf("%s.%s.%s", cpkg, cname, method),
                Index:      m.Index,
                Pool:       pool,
            })
        }
    }
    return nil
}

Last updated

Was this helpful?