goweb/cqrs/dispatcher.go

93 lines
1.8 KiB
Go

package cqrs
import (
"context"
)
type Dispatcher struct {
reg *Registry
cmdFactory CommandFactory
cmdResultFactory CommandResultFactory
qryFactory QueryFactory
qryResultFactory QueryResultFactory
}
func (d *Dispatcher) Exec(ctx context.Context, req CommandRequest) (CommandResult, error) {
cmd, err := d.cmdFactory(req)
if err != nil {
return nil, err
}
hdlr, mdlwrs, err := d.reg.MatchCommand(cmd)
if err != nil {
return nil, err
}
if len(mdlwrs) > 0 {
for i := len(mdlwrs) - 1; i >= 0; i-- {
hdlr = mdlwrs[i](hdlr)
}
}
if err := hdlr.Handle(ctx, cmd); err != nil {
return nil, err
}
result, err := d.cmdResultFactory(cmd)
if err != nil {
return nil, err
}
return result, nil
}
func (d *Dispatcher) Query(ctx context.Context, req QueryRequest) (QueryResult, error) {
qry, err := d.qryFactory(req)
if err != nil {
return nil, err
}
hdlr, mdlwrs, err := d.reg.MatchQuery(qry)
if err != nil {
return nil, err
}
if len(mdlwrs) > 0 {
for i := len(mdlwrs) - 1; i >= 0; i-- {
hdlr = mdlwrs[i](hdlr)
}
}
data, err := hdlr.Handle(ctx, qry)
if err != nil {
return nil, err
}
result, err := d.qryResultFactory(qry, data)
if err != nil {
return nil, err
}
return result, nil
}
func (d *Dispatcher) RegisterCommand(match MatchFunc, hdlr CommandHandler, mdlwrs ...CommandMiddleware) {
d.reg.RegisterCommand(match, hdlr, mdlwrs...)
}
func (d *Dispatcher) RegisterQuery(match MatchFunc, hdlr QueryHandler, mdlwrs ...QueryMiddleware) {
d.reg.RegisterQuery(match, hdlr, mdlwrs...)
}
func NewDispatcher(funcs ...OptionFunc) *Dispatcher {
opt := CreateOption(funcs...)
return &Dispatcher{
reg: NewRegistry(),
cmdFactory: opt.CommandFactory,
cmdResultFactory: opt.CommandResultFactory,
qryFactory: opt.QueryFactory,
qryResultFactory: opt.QueryResultFactory,
}
}