ABP Domain layer-domain event (domain events)

Source: Internet
Author: User
Tags eventbus


ABP Domain layer-domain event (domain events)


DDD-based Modern ASP.--ABP Series 14, ABP Domain layer-domain event (domain events)






The ABP is "ASP. Boilerplate Project (ASP. NET Template project) "for short.



ABP's official website : http://www.aspnetboilerplate.com



ABP's Open source project on GitHub : https://github.com/aspnetboilerplate






In C #, a class can define its own events and other classes can register the event and listen to it, and can get event notifications when an event is triggered. This is useful for desktop applications or for stand-alone Windows service. However, there is a problem with Web applications because objects are created based on requests (request) and their life cycles are short. It is difficult for us to register other categories of events. Similarly, the direct registration of other categories of events also results in the coupling of classes.



In application systems, domain events are used to decouple and reuse (re-use) business logic.


Event Bus


The event bus is a single (singleton) object that is shared by all other classes and can be used to trigger and handle events. To use this event bus, you need to reference it. You can do this in two ways:


Get the default instance (Getting the defaults instance)


You can use Eventbus.default directly. It is a global event bus and can be used in the following ways:


EventBus.Default.Trigger (...); Triggering events
Inject Ieventbus event interface (injecting Ieventbus)


In addition to using Eventbus.default directly, you can use a dependency injection (DI) method to obtain a ieventbus reference. This facilitates unit testing. Here, we use the paradigm of attribute injection:


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


Injection event bus, using attribute injection is more suitable than constructing sub-injection. The event is described by the class and the event object inherits from EventData. Suppose we want to trigger an event after a task has completed:


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


This class contains properties that are required for the class to handle the event. The EventData class defines the EventSource (the object that triggered the event) and the Eventtime (when triggered) property.


Defining events


The ABP defines the Abphandledexceptiondata event and automatically triggers the event when an exception occurs. This is especially useful if you want to get more information about the exception (even if the ABP has automatically logged all the exceptions). You can register this event and set its trigger timing to occur when an exception occurs.



The ABP also provides many common event data classes for entity changes: Entitycreatedeventdata, Entityupdatedeventdata, and Entitydeletedeventdata. They are defined in the Abp.Events.Bus.Entitis namespace. When an entity is added/updated/deleted, these events are automatically triggered by the ABP. If you have a person entity that can be registered to Entitycreatedeventdata, the event is triggered after the new person entity is created and inserted into the database. These events also support inheritance. If the student class inherits from the person class and you register to Entitycreatedeventdata, then you will receive a trigger when person or student is added.


Triggering events


Examples of triggering events are as follows:


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

       public void CompleteTask (CompleteTaskInput input) {
          // TODO: Completed tasks on the database
          EventBus.Trigger (new TaskCompletedEventData {TaskId = 42});
       }
    }


Here are some overloads of the triggering method:


ABP domain layer-Domain events A modern ASP.NET development framework based on DDD-ABP series 14, ABP domain layer-Domain events   ABP is short for "ASP.NET Boilerplate Project". ABP's official website: http://www.aspnetboilerplate.com ABP's open source project on Github: https://github.com/aspnetboilerplate    In C #, a class can define its own event and other classes can register for the event and listen for it, and get event notification when the event is triggered. This is useful for desktop applications or stand-alone Windows Services. However, it can be a bit problematic for web applications, because objects are created on request and their lifetimes are short. We have difficulty registering other categories of events. Similarly, the direct registration of events in other categories also creates coupling between classes.  In application systems, domain events are used to decouple and re-use business logic. Event bus The event bus is a singleton object, which is shared by all other classes, and can be used to trigger and process events. To use this event bus, you need to reference it. You can do this in two ways: Getting the default instance You can use EventBus.Default directly. It is a global event bus and can be used as follows: EventBus.Default.Trigger (...); // Trigger event Injecting IEventBus event interface In addition to using EventBus.Default directly, you can also use dependency injection (DI) to get a reference to IEventBus. This is good for unit testing. Here we use the paradigm of attribute injection:
 public class TaskAppService : ApplicaService {
      public IEventBus EventBus { get; set; }
      public TaskAppService() {
         EventBus = NullEventBus.Instance;
      }
   }

Injecting the event bus, using property injection is more suitable than constructor injection. An event is described by a class and the event object inherits from EventData. Suppose we want to trigger an event after a task is completed:

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

The properties that this class contains are all that the class needs to handle events. The EventData class defines the EventSource (that object triggered the event) and EventTime (when it triggered) properties.

Define event
 ABP defines the AbpHandledExceptionData event and automatically triggers this event when an exception occurs. This is especially useful when you want to get more information about anomalies (even if ABP has automatically logged all anomalies). You can register this event and set its trigger timing when an exception occurs.

ABP also provides many common event data classes for entity changes: EntityCreatedEventData, EntityUpdatedEventData and EntityDeletedEventData. They are defined in the Abp.Events.Bus.Entitis namespace. When an entity is added / updated / deleted, these events will be triggered automatically by ABP. If you have a Person entity, you can register to EntityCreatedEventData, and the event will be triggered after a new Person entity is created and inserted into the database. These events also support inheritance. If the Student class inherits from the Person class and you register it with EntityCreatedEventData, then you will receive a trigger when a Person or Student is added.

trigger event
 Examples of trigger events are as follows:


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

      public void CompleteTask(CompleteTaskInput input) {
         //TODO: Completed tasks on the database EventBus.Trigger(new TaskCompletedEventData { TaskId = 42 } );
      }
   }

Here are some overloads of trigger methods:

   EventBus.Trigger<TaskcompletedEventData>(new TaskCompletedEventData { TaskId = 42});
   EventBus.Trigger(this, new TaskCompletedEventData { TaskId = 42 });
   EventBus.Trigger(typeof(TaskCompletedEventData), this, new TaskCompletedEventData { TaskId = 42});
Event handling


To handle the event, you should implement the Ieventhandler interface as follows:


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


The Eventbus is integrated into the dependency injection system. As we implemented itransientdependency in the example above, when the taskcompleted event fires, it creates a new entity of the Activitywriter class and calls its Handleevent method, and then releases it. See the article on Dependency Injection (DI) for details.


Handling of the underlying event (handling base events)


Eventbus supports the inheritance of events. For example, you can create a taskeventdata and two inheritance classes: Taskcompletedeventdata and 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; }
   }


However, you can implement Ieventhandler to handle these two events:


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


Of course, you can also implement Ieventhandler to handle all the events, if you really want to do this (the translator note: The author does not recommend this way).


Handling Multiple events (handling multiple events)


We can handle multiple events in a single processor (handler). At this point, you should implement Ieventhandler for different events. Examples are as follows:


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


We must register the processor (handler) to the event bus to handle the event.


Automatic type automatically


The ABP scans all classes that implement the Ieventhandler interface and automatically registers them in the event bus. When an event occurs, it obtains the reference object of the processor (handler) through Dependency injection (DI) and releases it after the event has been processed. This is the more recommended event bus usage in the ABP.


Manual type (manually)


You can also register an event manually, but there are some problems. In a Web application, the registration of events should be done when the application starts. When a Web request arrives, the event is registered, and the behavior is repeated. This may cause some problems in your application because the registered class can be called multiple times. It is also important to note that manual registration cannot be used with a dependency injection system.



The ABP provides multiple overloads of the event Bus registration method (overload). One of the simplest overloaded methods is to wait for delegation (delegate) or lambda.


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


Therefore, the event: task completed occurs, and this lambda method is called. The second overloaded method waits for an object that implements the Ieventhandler:


Eventbus.register<taskcompletedeventdata> (New Activitywriter ());


The same example, if Activitywriter is called because of an event. This method also has a non-generic overload. The other overload accepts two generalization parameters:


Eventbus.register<taskcompletedeventdata, activitywriter> ();


At this point, the event bus creates a new activitywriter for each event. When it is released, it calls the Activitywriter.dispose method.



Finally, you can register an event processor factory (event handler factory) to be responsible for creating the processor. The processor factory has two methods: GetHandler and Releasehandler, examples are as follows:


public class ActivityWriterFactory: IEventHandlerFactory {
       public IEventHandler GetHandler () {
          return new ActivityWriter ();
       }
       public void ReleaseHandler (IEventHandler handler) {
          // TODO: release ActivityWriter entity (processor)
       }
    }


The ABP also provides a special factory class, Iochandlerfactory, which can be used to create or release (Dispose) processors through a dependency injection system. ABP can automatically register iochandlerfactory. Therefore, if you want to use a dependency injection system, use the automated registration method directly.


Unregister event


When you manually register the event bus, you may want to unregister it later. The simplest way to unregister an event is registration. Dispose (). Examples are as follows:


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


Of course, cancellation can take place at any time anywhere. Save (keep) a well-registered object and release (Dispose) it when you want to cancel the registration. All overloads of the registration Method (overload) Return an object that can be freed (disposable) to unregister the event.



The event bus also provides an unregister method. Examples of Use:


// Create a processor
var handler = new ActivityWriter ();
// Register an event
EventBus.Register <TaskCompletedEventData> (handler);
// Cancel the registration of this event
EventBus.Unregister <TaskCompletedEventData> (handler);


It also provides overloaded methods to unregister delegates and factories. The unregister processor object must be the same as the previously registered object.



Finally, Eventbus provides a UnregisterAll () method to cancel the registration of all processors for an event, while the UnregisterAll () method is all the processors for all events.






I hope that more domestic architects will be able to focus on the ABP project, and perhaps it will help you, perhaps with your participation, this project can develop better.



Welcome to add ABP Architecture Design Exchange QQ Group: 134710707



ABP Domain layer-domain event (domain events)


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.