package cqrs import ( "context" ) type Bus struct { reg *Registry cmdFactory CommandFactory cmdResultFactory CommandResultFactory qryFactory QueryFactory qryResultFactory QueryResultFactory } func (b *Bus) Exec(ctx context.Context, req CommandRequest) (CommandResult, error) { cmd, err := b.cmdFactory(req) if err != nil { return nil, err } hdlr, mdlwrs, err := b.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 := b.cmdResultFactory(cmd) if err != nil { return nil, err } return result, nil } func (b *Bus) Query(ctx context.Context, req QueryRequest) (QueryResult, error) { qry, err := b.qryFactory(req) if err != nil { return nil, err } hdlr, mdlwrs, err := b.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 := b.qryResultFactory(qry, data) if err != nil { return nil, err } return result, nil } func (b *Bus) RegisterCommand(match MatchFunc, hdlr CommandHandler, mdlwrs ...CommandMiddleware) { b.reg.RegisterCommand(match, hdlr, mdlwrs...) } func (b *Bus) RegisterQuery(match MatchFunc, hdlr QueryHandler, mdlwrs ...QueryMiddleware) { b.reg.RegisterQuery(match, hdlr, mdlwrs...) } func NewBus(funcs ...OptionFunc) *Bus { opt := CreateOption(funcs...) return &Bus{ reg: NewRegistry(), cmdFactory: opt.CommandFactory, cmdResultFactory: opt.CommandResultFactory, qryFactory: opt.QueryFactory, qryResultFactory: opt.QueryResultFactory, } }