package cqrs type CommandMiddleware func(next CommandHandler) CommandHandler type QueryMiddleware func(next QueryHandler) QueryHandler type Registry struct { commands []*commandHandler queries []*queryHandler } type commandHandler struct { Match MatchFunc Handler CommandHandler Middlewares []CommandMiddleware } type queryHandler struct { Match MatchFunc Handler QueryHandler Middlewares []QueryMiddleware } func (r *Registry) MatchCommand(cmd Command) (CommandHandler, []CommandMiddleware, error) { // TODO cache matching to avoid unnecessary ops for _, reg := range r.commands { matches, err := reg.Match(cmd) if err != nil { return nil, nil, err } if matches { return reg.Handler, reg.Middlewares, nil } } return nil, nil, ErrHandlerNotFound } func (r *Registry) MatchQuery(qry Query) (QueryHandler, []QueryMiddleware, error) { // TODO cache matching to avoid unnecessary ops for _, reg := range r.queries { matches, err := reg.Match(qry) if err != nil { return nil, nil, err } if matches { return reg.Handler, reg.Middlewares, nil } } return nil, nil, ErrHandlerNotFound } func (r *Registry) RegisterCommand(match MatchFunc, hdlr CommandHandler, mdlwrs ...CommandMiddleware) { r.commands = append(r.commands, &commandHandler{match, hdlr, mdlwrs}) } func (r *Registry) RegisterQuery(match MatchFunc, hdlr QueryHandler, mdlwrs ...QueryMiddleware) { r.queries = append(r.queries, &queryHandler{match, hdlr, mdlwrs}) } func NewRegistry() *Registry { return &Registry{ commands: make([]*commandHandler, 0), queries: make([]*queryHandler, 0), } }