sequence
This paper mainly studied eventhorizon Aggregate
Aggregate
eventhorizon/aggregate.go
type Aggregate interface {
// Entity provides the ID of the aggregate.
Entity
// AggregateType returns the type name of the aggregate.
// AggregateType() string
AggregateType() AggregateType
// CommandHandler is used to handle commands.
CommandHandler
}
type Entity interface {
// EntityID returns the ID of the entity.
EntityID() uuid.UUID
}
type CommandHandler interface {
HandleCommand(context.Context, Command) error
}
// AggregateType is the type of an aggregate.
type AggregateType string
// String returns the string representation of an aggregate type.
func (at AggregateType) String() string {
return string(at)
}
Copy the code
The Aggregate interface contains an Entity and a CommandHandler, and defines the AggregateType method
AggregateStore
eventhorizon/aggregate.go
// AggregateStore is responsible for loading and saving aggregates.
type AggregateStore interface {
// Load loads the most recent version of an aggregate with a type and id.
Load(context.Context, AggregateType, uuid.UUID) (Aggregate, error)
// Save saves the uncommittend events for an aggregate.
Save(context.Context, Aggregate) error
}
Copy the code
AggregateStore defines the Load and Save methods
AggregateStore
eventhorizon/aggregatestore/model/aggregatestore.go
// AggregateStore is an aggregate store that uses a read write repo for // loading and saving aggregates. type AggregateStore struct { repo eh.ReadWriteRepo eventHandler eh.EventHandler } var ( // ErrInvalidRepo is when a dispatcher is created with a nil repo. ErrInvalidRepo = errors.New("invalid repo") // ErrInvalidAggregate occurs when a loaded aggregate is not an aggregate. ErrInvalidAggregate = errors.New("invalid aggregate") ) // NewAggregateStore creates an aggregate store with a read write repo and an // event handler that can handle any resulting events (for example by publishing // them on an event bus). func NewAggregateStore(repo eh.ReadWriteRepo, eventHandler eh.EventHandler) (*AggregateStore, error) { if repo == nil { return nil, ErrInvalidRepo } d := &AggregateStore{ repo: repo, eventHandler: eventHandler, } return d, nil } // Load implements the Load method of the eventhorizon.AggregateStore interface. func (r *AggregateStore) Load(ctx context.Context, aggregateType eh.AggregateType, id uuid.UUID) (eh.Aggregate, error) { item, err := r.repo.Find(ctx, id) if errors.Is(err, eh.ErrEntityNotFound) { // Create the aggregate. if item, err = eh.CreateAggregate(aggregateType, id); err ! = nil { return nil, err } } else if err ! = nil { return nil, err } aggregate, ok := item.(eh.Aggregate) if ! ok { return nil, ErrInvalidAggregate } return aggregate, nil } // Save implements the Save method of the eventhorizon.AggregateStore interface. func (r *AggregateStore) Save(ctx context.Context, aggregate eh.Aggregate) error { if err := r.repo.Save(ctx, aggregate); err ! = nil { return err } // Handle any events optionally provided by the aggregate. if a, ok := aggregate.(eh.EventSource); ok && r.eventHandler ! = nil { for _, e := range a.Events() { if err := r.eventHandler.HandleEvent(ctx, e); err ! = nil { return err } } } return nil }Copy the code
AggregateStore defines the eh.ReadWriteRepo and eh.EventHandler properties. Its Load and Save methods are entrusted to eh.ReadWriteRepo
ReadWriteRepo
eventhorizon/repo.go
type ReadWriteRepo interface {
ReadRepo
WriteRepo
}
type ReadRepo interface {
// Parent returns the parent read repository, if there is one.
// Useful for iterating a wrapped set of repositories to get a specific one.
Parent() ReadRepo
// Find returns an entity for an ID.
Find(context.Context, uuid.UUID) (Entity, error)
// FindAll returns all entities in the repository.
FindAll(context.Context) ([]Entity, error)
}
type WriteRepo interface {
// Save saves a entity in the storage.
Save(context.Context, Entity) error
// Remove removes a entity by ID from the storage.
Remove(context.Context, uuid.UUID) error
}
Copy the code
The ReadWriteRepo interface combines the ReadRepo and WriteRepo interfaces. The ReadRepo interface defines the Parent, Find, and FindAll methods. The WriteRepo interface defines the Save and Remove methods
summary
Eventhorizon contains the Entity and CommandHandler embedded in the Aggregate interface, and defines the AggregateType method. AggregateStore defines Load and Save methods. The implementation class of AggregateStore defines eh.ReadWriteRepo and Eh. EventHandler properties, and its Load and Save methods are entrusted to Eh. ReadWriteRepo.
doc
- eventhorizon