diff --git a/mux.go b/mux.go index 7230308..900475e 100644 --- a/mux.go +++ b/mux.go @@ -2,6 +2,7 @@ package dew import ( "context" + "fmt" "reflect" "sync" ) @@ -166,16 +167,24 @@ func (mx *mux) updateHandler(m middlewareType) { } // Register adds the handler to the mux for the given command type. -func (mx *mux) Register(handler any) { - hdlTyp := reflect.TypeOf(handler) - for i := 0; i < hdlTyp.NumMethod(); i++ { - mtdTyp := hdlTyp.Method(i) - if isHandlerMethod(mtdTyp) { - cmdTyp := mtdTyp.Type.In(2).Elem() - if cmdTyp.Implements(reflect.TypeOf((*Action)(nil)).Elem()) { - mx.addHandler(cmdTyp, reflect.ValueOf(handler).Method(i).Interface()) - } else if cmdTyp.Implements(reflect.TypeOf((*QueryAction)(nil)).Elem()) { - mx.addHandler(cmdTyp, reflect.ValueOf(handler).Method(i).Interface()) +func (mx *mux) Register(handler interface{}) { + val := reflect.ValueOf(handler) + typ := val.Type() + + // Convert to pointer if not already + if typ.Kind() != reflect.Ptr { + val = reflect.New(typ) + val.Elem().Set(reflect.ValueOf(handler)) + typ = val.Type() + } + + for i := 0; i < typ.NumMethod(); i++ { + method := typ.Method(i) + if isHandlerMethod(method) { + cmdType := method.Type.In(2).Elem() + if cmdType.Implements(reflect.TypeOf((*Action)(nil)).Elem()) || + cmdType.Implements(reflect.TypeOf((*QueryAction)(nil)).Elem()) { + mx.addHandler(cmdType, val.Method(i).Interface()) } } } @@ -187,6 +196,7 @@ func (mx *mux) setupHandler() { mx.updateHandler(mQuery) } if mx.mHandlers[mDispatch] == nil { + println("setupHandler") mx.updateHandler(mDispatch) } if mx.parent != nil { @@ -195,6 +205,7 @@ func (mx *mux) setupHandler() { } func (mx *mux) addHandler(t reflect.Type, h any) { + println(fmt.Sprintf("addHandler: %v", t)) mx.entries.Store(t, &handler{handler: h, mux: mx}) } diff --git a/mux_test.go b/mux_test.go index d609b8b..73bfa3b 100644 --- a/mux_test.go +++ b/mux_test.go @@ -29,6 +29,19 @@ func TestMux_BasicCommand(t *testing.T) { } } +func TestMux_ValueTypeHandler(t *testing.T) { + var userHandler userHandler + + mux := dew.New() + mux.Register(userHandler) + + createUser := &createUser{Name: "john"} + testRunDispatch(t, dew.NewAction(mux, createUser)) + if createUser.Result != "user created" { + t.Fatalf("unexpected result: %s", createUser.Result) + } +} + func TestMux_HandlerNotFound(t *testing.T) { defer func() { if r := recover(); r == nil {