首页 技术 正文
技术 2022年11月15日
0 收藏 501 点赞 4,423 浏览 6502 个字

http://www.aspnetboilerplate.com/Pages/Documents/EventBus-Domain-Events

EventBus

EventBus是个单例,获得EventBus的引用可有下面两个方法:

默认的EventBus实例,使用EventBus.Default即可找到它。

EventBus.Default.Trigger(...); //trigger an event

为单元测试考虑,更好的做法是通过依赖注入,获得EventBus的引用,下面是通过属性注入的代码:

public class TaskAppService : ApplicationService
{
public IEventBus EventBus { get; set; } public TaskAppService()
{
EventBus = NullEventBus.Instance;
}
}

使用属性注入比通过构造函数注入更好。上面代码令EventBus初始化为 NullEventBus.Instance,跟ILogger一样的做法。可以参考https://en.wikipedia.org/wiki/Null_Object_pattern对Null对象模式的详细介绍。

 自定义事件

 

让事件类继承于EventData:

public class TaskCompletedEventData : EventData
{
public int TaskId { get; set; }
}

EventData class defines EventSource (which object triggered the event) and EventTime(when it’s triggered) properties.

EventData类定义了EventSource (触发事件的源对象)和EventTime(何时触发)属性。

 ABP已经定义好的事件

ASP.NET Boilerplate defines AbpHandledExceptionData and triggers this event when it automatically handles any exception. This is especially useful if you want to get more information about exceptions (even ASP.NET Boilerplate automatically logs all exceptions). You can register to this event to be informed when an exception occurs.

There are also generic event data classes for entity changes: EntityCreatedEventData<TEntity>EntityUpdatedEventData<TEntity> and EntityDeletedEventData<TEntity>. They are defined in Abp.Events.Bus.Entities namespace. These events are automatically triggered by ASP.NET Boilerplate when an entity is inserted, updated or deleted. If you have a Person entity, can register to EntityCreatedEventData<Person> to be informed when a new Person created and inserted to database. These events also supports inheritance. If Student class derived from Person class and you registered to EntityCreatedEventData<Person>, you will be informed when a Person or Student inserted.

触发事件

public class TaskAppService : ApplicationService
{
public IEventBus EventBus { get; set; } public TaskAppService()
{
EventBus = NullEventBus.Instance;
} public void CompleteTask(CompleteTaskInput input)
{
//TODO: complete the task on database...
EventBus.Trigger(new TaskCompletedEventData {TaskId = 42});
}
}

Trigger方法有几个重载:


EventBus.Trigger<TaskCompletedEventData>(new TaskCompletedEventData { TaskId = 42 }); //Explicitly declare generic argument
EventBus.Trigger(this, new TaskCompletedEventData { TaskId = 42 }); //Set 'event source' as 'this'
EventBus.Trigger(typeof(TaskCompletedEventData), this, new TaskCompletedEventData { TaskId = 42 }); //Call non-generic version (first argument is the type of the event class)

处理事件

需要实现IEventHandler<T>:

public class ActivityWriter : IEventHandler<TaskCompletedEventData>, ITransientDependency
{
public void HandleEvent(TaskCompletedEventData eventData)
{
WriteActivity("A task is completed by id = " + eventData.TaskId);
}
}

EventBus is integrated with dependency injection system. As we implemented ITransientDependency above, when a TaskCompleted event occured, it creates a new instance of ActivityWriter class and calls it’s HandleEvent method, then disposes it. See dependency injection for more.

处理单个事件

Eventbus支持事件的继承:

public class TaskEventData : EventData
{
public Task Task { get; set; }
}public class TaskCreatedEventData : TaskEventData
{
public User CreatorUser { get; set; }
}public class TaskCompletedEventData : TaskEventData
{
public User CompletorUser { get; set; }
}

在事件处理类里对事件子类进行判断即可:

public class ActivityWriter : IEventHandler<TaskEventData>, ITransientDependency
{
public void HandleEvent(TaskEventData eventData)
{
if (eventData is TaskCreatedEventData)
{
//...
}
else if (eventData is TaskCompletedEventData)
{
//...
}
}
}

同时处理多个事件

一个事件处理类就可以同时处理多个事件,只需要实现多个IEventHandler<T>:

public class ActivityWriter :
IEventHandler<TaskCompletedEventData>,
IEventHandler<TaskCreatedEventData>,
ITransientDependency
{
public void HandleEvent(TaskCompletedEventData eventData)
{
//TODO: handle the event...
} public void HandleEvent(TaskCreatedEventData eventData)
{
//TODO: handle the event...
}
}

注册事件处理器

自动注册

 

建议使用自动注册,也就是什么都不用干。因为ABP会自动扫描事件处理类,在事件触发时自动使用依赖注入来取得处理器对象来处理事件,并在最后释放处理器对象。

 

手动注册

手动注册一般不会用到,这里就不翻译了。

It is also possible to manually register to events but use it with caution. In a web application, event registration should be done at application start. It’s not a good approach to register to an event in a web request since registered classes remain registered after request completion and keep re-registering for each request. This may cause problems for your application since registered class can be called multiple times. Also keep in mind that manual registration does not use dependency injection system.

There are some overloads of register method of the event bus. The simplest one waits a delegate (or a lambda):

EventBus.Register<TaskCompletedEventData>(eventData =>
{
WriteActivity("A task is completed by id = " + eventData.TaskId);
});

Thus, then a ‘task completed’ event occurs, this lambda method is called. Second one waits an object that implements IEventHandler<T>:

EventBus.Register<TaskCompletedEventData>(new ActivityWriter());

Same instance ıf ActivityWriter is called for events. This method has also a non-generic overload. Another overload accepts two generic arguments:

EventBus.Register<TaskCompletedEventData, ActivityWriter>();

In this time, event bus created a new ActivityWriter for each event. It calls ActivityWriter.Dispose method if it’s disposable.

Lastly, you can register a event handler factory to handle creation of handlers. A handler factory has two methods: GetHandler and ReleaseHandler. Example:

public class ActivityWriterFactory : IEventHandlerFactory
{
public IEventHandler GetHandler()
{
return new ActivityWriter();
} public void ReleaseHandler(IEventHandler handler)
{
//TODO: release/dispose the activity writer instance (handler)
}
}

There is also a special factory class, the IocHandlerFactory, that can be used to use dependency injection system to create/release handlers. ASP.NET Boilerplate also uses this class in automatic registration mode. So, if you want to use dependency injection system, directly use automatic registration.

取消注册

手动注册后,可能还有手动取消注册的需求,这个也不翻译了。

When you manually register to event bus, you may want to unregister to the event later. Simplest way of unregistering an event is disposing the return value of theRegister method. Example:

//Register to an event...
var registration = EventBus.Register<TaskCompletedEventData>(eventData => WriteActivity("A task is completed by id = " + eventData.TaskId) );//Unregister from event
registration.Dispose();

Surely, unregistration will be somewhere and sometime else. Keep registration object and dispose it when you want to unregister. All overloads of the Register method returns a disposable object to unregister to the event.

EventBus also provides Unregister method. Example usage:

//Create a handler
var handler = new ActivityWriter();//Register to the event
EventBus.Register<TaskCompletedEventData>(handler);//Unregister from event
EventBus.Unregister<TaskCompletedEventData>(handler);

It also provides overloads to unregister delegates and factories. Unregistering handler object must be the same object which is registered before.

Lastly, EventBus provides a UnregisterAll<T>() method to unregister all handlers of an event and UnregisterAll() method to unregister all handlers of all events.

下一篇: ICMP
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,087
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,562
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,412
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,185
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,821
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905