The *aggregate.Base type embeds a command.Handler to allow registration of commands in the aggregate constructor, like this:
package example
type Movie struct {
*aggregate.Base
}
func NewMovie(id uuid.UUID) *Movie {
m := &Movie{Base: aggregate.New(...))
command.ApplyWith(m, m.Create, "movie.create")
return m
}
type CreateParams struct {
Name string
Rating int8
}
func (m *Movie) Create(params CreateParams) error {
// aggregate.Next(...)
return nil
}
This works well as long as the Create method does not depend on any external dependencies, like it does in the following example (context.Context and RatingService):
package example
type Movie struct {
*aggregate.Base
}
func NewMovie(id uuid.UUID) *Movie {
m := &Movie{Base: aggregate.New(...))
command.ApplyWith(m, func(name string) error {
// Here, we would need access to a context.Context and RatingService
return m.Create(???, name, ???)
}, "movie.create")
return m
}
type CreateParams struct {
Name string
Rating int8
}
type RatingService interface {
Rating(ctx context.Context, name string) (int8, error)
}
func (m *Movie) Create(ctx context.Context, name string, svc RatingService) error {
rating, err := svc.Rating(ctx, name)
if err != nil {
return err
}
aggregate.Next(m, "movie.created", CreateParams{
Name: name,
Rating: rating,
})
return nil
}
Ideas
a.command.ApplyContextWith helper
Idea: Add a new command.ApplyContextWith helper function to register command handlers that accept a generic command.Context type.
package example
type Movie struct { ... }
func NewMovie() *Movie {
m := &Movie{...}
command.ApplyContextWith(m, func(ctx command.Ctx[string]) error {
name := ctx.Payload()
return m.Create(ctx, name, ???) // still no RatingService available
}, "movie.create")
return m
}
b. Dependency Injection Container
Idea: Provide a DI Container to command.Context to provide dependencies to aggregates when setting up commands.
Context
The
*aggregate.Base
type embeds acommand.Handler
to allow registration of commands in the aggregate constructor, like this:This works well as long as the
Create
method does not depend on any external dependencies, like it does in the following example (context.Context
andRatingService
):Ideas
a.
command.ApplyContextWith
helperIdea: Add a new
command.ApplyContextWith
helper function to register command handlers that accept a genericcommand.Context
type.b. Dependency Injection Container
Idea: Provide a DI Container to
command.Context
to provide dependencies to aggregates when setting up commands.