ABP框架 – 领域事件(EventBus)

文档目录

1.依照系列文章的目的

 

 

本节情:

实现一个稍微而得意的出品级别php框架

EventBus

温馨动手实现一个初框架只是用于学习交流,不打算替代市场上存活的其它主流框架。

  • 注入
    IEventBus 
  • 获得默认实例

 

概念事件

 

预定义事件

2. 自己如果一个如何的PHP框架

  • 拍卖完毕异常
  • 实业改

简易实用,安全优雅,博采众长

接触事件

 

处理事件

装简便,上手简单,扩展简单

  • 处理基类事件
  • 处理程序异常
  • 拍卖多独事件

免待编译C扩展。

处理程序注册

不需要了解什么是composer。

  • 自动
  • 手动

非需改nginx.cnf .htaccess各种重写规则。

反注册

但是支撑各种条件,从最低端的虚拟空间及独服务器,从单机xampp,phpstudy,

 

到各种云sae,bae,以及巨大上之分布式架构部署方式。绿色无需安装,复制即用。

在C#里,一个好像可定义自己的波,然后另外类可登记它,当某些事情发时,接收至通知。这对桌面应用或单机的Windows服务非常实惠。但是,对于一个Web应用,它就有接触问题,因为对象在一个web请求里创建,并且她生命周期都生紧缺。所以就是寸步难行注册一些像样事件,同时,直接登记外一个近似的事件,也如得类之间越是藕合。

 

世界事件一般用来解藕业务逻辑与以运用里有重要领域改时发出通报。

概括的代码结构。

 

尚无很处理。

EventBus

从来不命名空间。

EventBus是一个单例对象,被有着类触发事件还是处理事件时共享。为运用事件总线,你先要引用它,有少种办法。

靡类似继承。

 

莫设计模式。

注入 IEventBus

莫说明新名词。

汝可以用倚注入收获一个IEventBus的援,这儿我们以性质注入模式:

尚未crud链式操作。

public class TaskAppService : ApplicationService
{
    public IEventBus EventBus { get; set; }

    public TaskAppService()
    {
        EventBus = NullEventBus.Instance;
    }
}

尚未说明新签语言。

当流事件总线上,属性注入比构造器注入更合适。你的好像可以没有事件总线,NullEventBus实现了拖欠对象模式,当你调用它的点子时,方法里啊为不开。

靡一系列log。

 

莫运用单元测试。

得默认实例

 

苟您莫可知注入其,可以直接采用EventBus.Default。它是大局的风波总线,使用办法如下所示:

一半天达标亲手,简单好亮。

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

那么起什么?

以旁可能的地方还无建议直接使用EventBus.Default,因为它们难让单元测试。

 

 

mcv文件组织,url路由,mysql辅助。

概念事件

redis也没有。

每当触发一个轩然大波前,你首先要定义其,通过一个连续自EventData的类似来显现一个风波。假设当一个职责就后我们想点一个波:

 

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

安康优雅

这类似富含处理事件类所欲的属性,EventData类定义了EventSource(事件源,哪个目标触发了风波)和EventTime(何时触发的)属性。

输入安全, 输出安全,文件上传安全

 

 

预定义事件

博采众长

拍卖完毕异常

各种风味简单接抱,快速进入其他类库

ABP定义了AbpHandledExceptionData,并当ABP自动处理外异常时,会接触这个波,这当你想打听再多异常信息经常越有因此(尽管ABP自动记录了拥有大)。你可以登记之事件,当大出常,发出通报。

 

实体改

否实体改提供了泛型的事件:EntityCreationEventData<Tentity>、EntityCreatedEventData<TEntity>、EntityUpdatingEventData<TEntity>、EntityUpdateEventData<TEntity>、EntityDeletingEventData<TEntity>和EntityDeletedEventData<TEntity>,同样为来EntityChangingEventData<TEntity>和EntityChangedEventData<TEntity>,修改好是插、更新或删除。

“ing”事件(例如EntityUpdating)在保存修改(SaveChanges)前点,所以您得在这些事件里,通过废除来深,促使行事单元转头滚,阻止操作)。“ed”事件(例如EntityUpdated)在保存修改之后让硌,也便从未机会吃工作单元回滚了。

实体改事件定义在Abp.Events.Bus.Entities命名空间里,并在插入、更新或删除实体时,被ABP自动触发。如果您发出一个Person实体,你得注册EntityCreatedEventData<Person>,当一个初的Person创建并插入到数据库后,就得收起通知。这些事件吧支撑继承,如果你有一个蝉联自Person的Student类,并且注册了EntityCreatedEventData<Person>,当一个Person或Student被插后,你也会收到通知。

 

点事件

接触一个轩然大波颇简短:

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)

接触事件之其余一个艺术是:使用AggregateRoot类的DomainEvents集合(查看实业文档的相关小节)。

 

处理事件

呢处理一个事变,你应当实现IEventHandler<T>接口,如下所示:

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

IEventHandler定义了HandleEvent方法,并像上面那样实现其。

EventBus被整合及因注入系统里,如我们地方那样实现ITransientDependency,当一个TaskCompleted事件来后,它创建一个初的ActivityWriter实例,并调用它的HandleEvent方法,然后放它,更多信息查阅靠注入。

 

拍卖基类事件

EventBus支持事件的继续,例如:你可创造一个TaskEventData和有限独子类:TaskCompletedEventData和TaskCreatedEventData:

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; }
}

接下来您得兑现IEventhandler<TaskEventData>来拍卖当下点儿栽事件:

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

立即也不怕意味着,你可兑现IEventHandler<EventData>来拍卖利用被之享有事件,你恐怕无思量然做,但其是足以完成的。

 

处理程序异常

在处理程序(Handler)抛来一个/一些大时,Eventbus触发所有Handler事件,如果只是来一个处理程序抛来深,异常会直接吃Trigger方法抛出,如果多个处理程序抛来怪,EventBus只吗它丢来一个AggregateException异常。

 

处理多只事件

以一个处理程序里而可以拍卖多单事件,此次,你应该也每个事件实现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找到有实现IEVentHandler的类并注册到依靠注入(例如:通过兑现ITransientDependency,如上面的言传身教),然后ABP自动把其注册及事件总线,当一个事变来,ABP使用依赖注入得到处理程序的援,并于事件处理后放该引用。在ABP里,这是用事件总线的推介的主意。

 

手动

可手动注册事件,但如果小心使用。在一个web应用里,事件注册应当吃行使启动里就。在一个Web请求里,注册事件未是一个好的不二法门,因为注册类请好后持续注册,并也每个请求又登记,这可能会见惹问题,因为注册类多次叫调用。同时如果牢记,手动注册不利用依赖注入系统。

事件总线的Register方法有几个重载,最简易的凡承受一个信托(或lambda):

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

“任务就”事件有后,这个lambda方法就是会见被调用。第二单是承受一个兑现了IEventHantler<T>的对象:

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

一致是为事件调用ActivityWriter实例。第三单重载接受两只泛型参数:

EventBus.Register<TaskCompletedEventData, ActivityWriter>();

本次,事件总线为每个事件创建一个初的ActivityWriter,如果它是disposable(可释放),并调用ActivityWriter.Dispose方法。

末了,你可挂号一个事件处理程序工作,负责处理程序的开创。一个处理程序工厂发生星星点点单办法:GetHandler和ReleaseHandler。例如:

public class ActivityWriterFactory : IEventHandlerFactory
{
    public IEventHandler GetHandler()
    {
        return new ActivityWriter();
    }

    public void ReleaseHandler(IEventHandler handler)
    {
        //TODO: release/dispose the activity writer instance (handler)
    }
}

再有一个奇之厂子类IocHandlerFactory。它使用依赖注入系统来创造/释放处理程序。ABP在机关注册里为祭此类似,所以,如果您想使依赖注入系统,直接运用之前定义的自行注册。

 

反注册

当您为事件总线注册后,想反注册事件,最简易的法门就是释放Register方法返回的价值,例如:

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

//Unregister from event
registration.Dispose();

当然,其它地方或任何某个时刻,都或用反注册,你得保留注册对象并以用常释放它。Register方法的具有重载都回一个可是放的目标吃事件。

EventBus也供了Unregister方法,使用示例:

//Create a handler
var handler = new ActivityWriter();

//Register to the event
EventBus.Register<TaskCompletedEventData>(handler);

//Unregister from event
EventBus.Unregister<TaskCompletedEventData>(handler);

她吧供了重载来反而注册委托以及工厂。反注册处理程序对象要是挂号时的靶子。

末了,EventBus提供了一个UnregisterAll<T>()方法,它反而注册一个波的保有处理程序,UnregisterAll()方法反注册所有事件之所有处理程序。

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注