聊聊eventhorizon的Aggregate

本文主要研究一下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)
}

Aggregate接口内嵌了Entity及CommandHandler,定义了AggregateType方法

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
}

AggregateStore定义了Load、Save方法

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
}

AggregateStore定义了eh.ReadWriteRepo、eh.EventHandler属性;其Load、Save方法均委托给了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
}

ReadWriteRepo接口组合了ReadRepo、WriteRepo接口;其中ReadRepo接口定义了Parent、Find、FindAll方法;WriteRepo接口定义了Save、Remove方法

小结

eventhorizon的Aggregate接口内嵌了Entity及CommandHandler,定义了AggregateType方法;AggregateStore定义了Load、Save方法;AggregateStore的实现类定义了eh.ReadWriteRepo、eh.EventHandler属性,其Load、Save方法均委托给了eh.ReadWriteRepo。

doc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IJSRuntime是一个接口,用于在Blazor应用程序中与JavaScript进行交互。在Blazor组件或页面中,可以通过将IJSRuntime注入来使用它。例如,可以将IJSRuntime注入到Razor组件或页面的属性中,以便在需要时直接使用它。通过调用Invoke方法,可以在IJSInProcessRuntime实例上同步调用JavaScript函数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ASP.NET Core Blazor: 两种IJSRuntime依赖注入的方式](https://blog.csdn.net/bdbox/article/details/129990791)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [EventHorizon.Blazor.Server.Interop](https://download.csdn.net/download/weixin_42107374/18753521)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Blazor中C#与Javascript的互操作](https://blog.csdn.net/weixin_46295080/article/details/107924579)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值