如何构建通用的 IEventHandler?

How do I build a generic IEventHandler?

我读过https://aspnetboilerplate.com/Pages/Documents/EventBus-Domain-Events and also ABP's implementation of Entity event handlers https://github.com/aspnetboilerplate/aspnetboilerplate/tree/f10fa5205c780bcc27adfe38aaae631f412eb7df/src/Abp/Events/Bus/Entities

我在工作中花了 8 个小时试图找到我的问题的解决方案,但我没有成功。

我有一些实体指向一个名为 DatumStatus 的实体,它记录了生成不同状态的某些操作,例如:批准、修改、审查、存档等。

我正在尝试生成一个能够根据这些操作修改其状态的通用 EventHandler。

一个基于算法的例子:

EventBus.Trigger(new ApproveEventData{
    Repository = _certainRepository,
    Ids = [1, 4, 5]
});

处理程序本身将依次处理此状态转换

public void HandleEvent(ApproveEventData eventData)
{
    eventData.Repository.Where(p => p.Id.IsIn(eventData.Ids)).ForEach(p => {
        p.Approved = true;
        p.ApprovalDate = DateTime.Now()
    });
}

问题是,我需要编写一个通用的 ApproveEventData 和能够为每个实体触发相同 HandleEvent 的处理程序。

我得到的"closest"是:

EventBus.Trigger(typeof(ApproveEventData<int>), (IEventData) new ApproveEventData<int> {
    Repository = (IRepository<EntityWithStatus<int>, int>) _entityRepository,
    Ids = selectedIds
});

[Serializable]
public class ApproveEventData<TPrimaryKey> : EventData
{
    public IRepository<EntityWithStatus<TPrimaryKey>, TPrimaryKey> Repository;
    public TPrimaryKey[] Ids;
}

上面的实现在转换存储库时失败。

有人可以解释一下吗?谢谢!

我看到了两种可能的方法。

  1. 依赖协变和逆变。您可以通过使 EntityWithStatus 的接口成为接口并使 IEntityWithStatus 和 IRepository 协变(添加到通用类型定义中)来使转换成功。

  2. 依赖动态并利用泛型类型推断。基本上让存储库是动态的。

我推荐第 1 个。