In C #, we can define our own events in one class, and other classes can subscribe to the event, and when something happens, you can notify the class. This is useful for desktop applications or for standalone Windows services. But for a Web application it is a bit problematic because objects are created in Web requests and these objects have a short life cycle, so registering some class of events is difficult. In addition, registering events from other classes can make classes tightly coupled. The event bus can be used to decouple and reuse the logic in the application.
The benefits of event bus and the problems introduced
The advantage is obvious, is independent 发布订阅模块
of one, the caller can use this module, shielding some thread switching problems, simple implementation of the Publish subscription function.
The downside may be subtle, but these need to be enough to attract our attention.
- A lot of abuse, will lead to the spread of logic, problems after the problem is difficult to locate.
- There is no way to implement strong typing, and you will find problems when compiling.
- There are some problems with code readability, and the IDE does not recognize these protocols and is unfriendly to the IDE.
Always, if there is a lot of event interaction in the project, you can still
EventBus
To implement it, or recommend that you implement it inside the module
观察者模式。
Sample code
So today we introduce a simple event bus, which is the implementation of the event release subscription pattern, which allows us to decouple the design of our modules and domain boundaries with the weak reference nature of events in domain-driven design (DDD).
Currently, all source code has been submitted to GitHub, address: Https://github.com/weizhong1988/Weiz.EventBus
The program directory structure is as follows:
Event Bus
An event bus is a singleton object that is shared by all other classes that trigger and handle events. To use the event bus, you should first get a reference to it. There are two ways to handle this:
Subscribe to Events
Before triggering an event, you should define the event first. Eventbus provides us with the Subscribe method to subscribe to events:
Public voidSubscribe<tevent> (ieventhandler<tevent> EventHandler)wheretevent:ievent {//Sync Lock Lock(_syncobject) {//get the type of domain model varEventType =typeof(tevent); //If this realm type has been registered in the event bus if(_diceventhandler.containskey (EventType)) {varHandlers =_diceventhandler[eventtype]; if(Handlers! =NULL) {handlers. ADD (EventHandler); } Else{handlers=Newlist<Object>{EventHandler}; } } Else{_diceventhandler.add (EventType,Newlist<Object>{eventHandler}); } } }
So the events are all integrated from IEvent, which contains the properties required for class handling events.
var New varNewvarnew useraddedeventhandlersendredbags (); Weiz.EventBus.Core.EventBus.Instance.Subscribe (Sendemailhandler); Weiz.EventBus.Core.EventBus.Instance.Subscribe (Sendmessagehandler); weiz.eventbus.core.eventbus.instance.subscribe<usergeneratorevent> (sendredbagshandler); Weiz.eventbus.core.eventbus.instance.subscribe<ordergeneratorevent> (Sendredbagshandler);
Publish Events
For event sources, you can publish events through the Publish method. Triggering an event is simple as follows:
Public voidPublish<tevent> (Tevent tevent, Action<tevent,BOOL, Exception> Callback)wheretevent:ievent {varEventType =typeof(tevent); if(_diceventhandler.containskey (EventType) && _diceventhandler[eventtype]! =NULL&&_diceventhandler[eventtype]. Count>0) { varHandlers =_diceventhandler[eventtype]; Try { foreach(varHandlerinchhandlers) { varEventHandler = Handler asIeventhandler<tevent>; Eventhandler.handle (tevent); Callback (Tevent,true,NULL); } } Catch(Exception ex) {callback (tevent,false, ex); } } Else{callback (tevent,false,NULL); } }
The following is a call to publish an event:
var New ordergeneratorevent {OrderId = guid.newguid ()}; System.Console.WriteLine ("{0} order succeeded ", Ordergeneratorevent.orderid); Weiz.EventBus.Core.EventBus.Instance.Publish (Ordergeneratorevent, CallBack);
Defining Handling Events
To handle an event, you should implement the Ieventhandler interface as follows:
/// <summary> /// Send email /// </summary> Public class Useraddedeventhandlersendemail:ieventhandler<usergeneratorevent> { public void Handle (usergeneratorevent tevent) { System.Console.WriteLine ( String. Format ("{0} message sent ", Tevent.userid));} }
Handling Multiple Events
Multiple events can be handled in a single processing handle. At this point, you should implement Ieventhandler for each event. Like what:
/// <summary> ///Red bags. /// </summary> Public classUseraddedeventhandlersendredbags:ieventhandler<usergeneratorevent>,ieventhandler<ordergeneratorevent > { Public voidHandle (ordergeneratorevent tevent) {System.Console.WriteLine (string. Format ("The next red envelope for {0} has been sent", Tevent.orderid)); } Public voidHandle (usergeneratorevent tevent) {System.Console.WriteLine (string. Format ("registered Red envelopes for {0} have been sent", Tevent.userid)); } }
At last
Above, the event bus is finished, complete code, please go to github download, this is just a simple implementation of Eventbus, you can according to their actual situation and needs, optimize the changes.
C # Summary (vi) Use of the Eventbus event Bus-Implement the event bus yourself