在 Reface.AppStarter 中使用事件总线

Posted shimizushiori

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 Reface.AppStarter 中使用事件总线相关的知识,希望对你有一定的参考价值。

大家对 设计模式 中的 监听者模式 肯定是非常熟悉的。

.Net 中的 事件 就是一个 监听者模式 很好的实践,你只需要以下几个步骤就可以实现这个功能

  1. 声明一个继承于 EventArgs 的事件参数
  2. 声明一个 event EventHandler<YourEventArgs> 的事件
  3. 在需要的时候,可以对事件进行触发
  4. 外部通过 += 操作监听事件

但是
当我们的系统内的组件越来越多,事件的监听关系就会变得很复杂。

举个例子
我们为 WebApi 开发一个删除用户的功能,
我们首先想到的是,向 UserController 中添加一个 Delete 操作,传个 Id 什么的,然后调用 IUserService.DeleteById(id) 就搞定了。

但是想想看,用户这类数据,可不是说能删就能删的,不管怎么说,删除以前多少要考虑一下能不能删,删除以后也要考虑一下,有没有什么连带数据需要清理。
借鉴 监听者模式 的思路,我们很容易设计如一个带有事件的 IUserService

public class UserDeletingEventArgs : EventArgs
{
    public int UserId { get; set; }
	
	// 是否可以删除,事件的处理者可以将此置为 false
    public bool CanDelete { get; set; }
	
	// 当不能删除时的原因,由事件的处理者填写
    public string DeletePreventedReason { get; set; }
}

public interface IUserService
{
    event EventHandler<UserDeletingEventArgs> Deleting;
    event EventHandler<UserDeletedEventArgs> Deleted;
	
	void DeleteById(int id);
}

如此一来,我们只要在实现 DeleteById 时触发两个事件即可

public void DeleteById(int id)
{
	UserDeletingEventArgs userDeletingEventArgs = new UserDeletingEventArgs(id);
	this.Deleting?.Invoke(this, userDeletingEventArgs);
	if(!userDeletingEventArgs.CanDelete)
		throw ......
	// delete user
	this.Deleted?.Invoke(this, new UserDeletedEventArgs(id));
}

通过上面的方法,我们轻松的构建了一个具有删除前后通知,并允许删除前拦截的 IUserService

然而,应用起来,往往并不乐观。

当我们在 Controller 中创建了 IUserService (无论是基于注入、工厂还是 new 的) 后,我们无法知道这个系统里面都有谁需要监听这个事件。
于是我们无法在 DeletingDeleted 中通知到所有的组件。






以上是关于在 Reface.AppStarter 中使用事件总线的主要内容,如果未能解决你的问题,请参考以下文章

Reface.AppStarter 框架初探

Vue事件在组件中的简单使用以及子组件事件触发父组件自定义事件

在 Unity 中使用委托和事件创建事件管理器(消息系统)

在事件驱动的嵌入式系统中使用事件队列避免竞争条件

winform中怎么使用EventLog控件记录事件日志

如何在模块中填充集合以在事件/命令中使用