This repository has been archived by the owner on Sep 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
eventbroker.html
182 lines (163 loc) · 8.84 KB
/
eventbroker.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
---
layout: documentation
title: EventBroker
teaser: Decoupled eventing with automatic thread switching
navigation:
- name: Overview
link: eventbroker.html
- name: Tutorial
link: eventbrokertutorial.html
- name: Registration by Attribute
link: eventbrokerregistrationbyattribute.html
- name: Registration over Interface
link: eventbrokerregistrationoverinterface.html
- name: Registration by Registrar
link: eventbrokerregistrationbyregistrar.html
- name: Simplified Handler Methods
link: eventbrokersimplifiedhandlermethods.html
- name: Direct Interaction
link: eventbrokerdirectinteraction.html
- name: Handlers
link: eventbrokerhandlers.html
- name: Matchers
link: eventbrokermatchers.html
- name: Exception Handling
link: eventbrokerexceptionhandling.html
- name: Extensions
link: eventbrokerextensions.html
- name: Logging
link: eventbrokerlogging.html
- name: Testability
link: eventbrokertestability.html
- name: Tips and Tricks
link: eventbrokertipsandtricks.html
- name: Specifications
link: eventbrokerspecifications.html
---
<h1>Event Broker</h1>
<a href="https://www.nuget.org/packages/Appccelerate.EventBroker/">
<img src="http://img.shields.io/nuget/v/Appccelerate.EventBroker.svg" title="latest version" />
<img src="http://img.shields.io/nuget/dt/Appccelerate.EventBroker.svg" title="number of downloads" />
</a>
<a href="https://www.myget.org/gallery/appccelerate">
<img src="https://img.shields.io/myget/appccelerate/v/Appccelerate.EventBroker.svg" title="latest alpha version" />
</a>
<a href="https://github.com/appccelerate/eventbroker/issues">
<img src="https://img.shields.io/github/issues/appccelerate/EventBroker.svg" title="open issues" />
</a>
<h2>Motivation</h2>
<p>
Using .net events throughout the application brings along some problems.
For example if you have an event that can be fired by several sources, interested instances need to know every single source and
need to register the event directly on them.
Doing so, the classes in the application become tangled.
This raises problems when you need to change the routing of events because you have to change the code in a lot of places.
</p>
<p>
Furthermore, in plug-in architectures, the plug-in should not access classes internal to the core directly.
Therefore it's difficult to integrate them into the notification infrastructure.
</p>
<p>
Finally, .net events are handled always on the same thread as the one the event was fired.
When listening for example to an event fired by a worker thread on a UI component, the UI component always has to check whether
thread switching to the user interface thread is needed and if so switch the thread before manipulating the user interface elements.
Otherwise, a cross-thread exception will occur (in debug mode) or you put your application at risk of failure (in release mode).
</p>
<p>
The event broker of Appccelerate solves these problems for you.
</p>
<h2>Features</h2>
<p>
<ul class="check dotted">
<li>Synchronous and asynchronous notifications</li>
<li>Automatic thread switching: to background or UI thread</li>
<li>Loose coupling of event topic publishers and subscribers</li>
<li>Publishers and subscribers are referenced by weak references</li>
<li>Multiple publishers and/or subscribers for a single event topic</li>
<li>Matchers for publications and subscriptions to control routing</li>
<li>Thorough customizable logging</li>
<li>Extension support for extending event broker functionality</li>
</ul>
</p>
<p>
<i>For a quick introduction see the <a href="eventbrokertutorial.html">Tutorial</a>.</i><br/>
<i>For the specification see <a href="eventbrokerspecifications.html">Specification</a></i>
</p>
<h2>EventBroker</h2>
<img src="img/eventbroker.png" alt="EventBroker overview"/>
<p>
The EventBroker takes the role of a mediator between publishers - instances firing events - and subscribers - instances listening to events.
This decouples publisher and subscribers because they only need to know the event broker and the event topic they are interested in.
</p>
<p>
This also gives you the possibility to define multiple publishers and/or subscribers for a single event topic.
Therfore, it is very easy to add or remove additional publishers or subscribers wihtout the need to change any existing code.
</p>
<p>
Automatic thread switching can easily be used by simply specifing on the subscriber how the event should be handled:
on the same thread as the publisher fired the event, on a background thread or on the user interface thread.
</p>
<h3><a href="eventbrokerregistrationbyattribute.html">Registration of Publishers and Subscribers by Attribute</a></h3>
<p>
The normal way how publishers and subscribers mark the events or event handler methods so that the event broker recognizes them is by attributes.
You simply mark an event with the <code>[EventPublication]</code> attribute. Likewise, a handler method is marked with <code>[EventSubscription]</code>.
</p>
<h3><a href="eventbrokerregistrationoverinterface.html">Registration of Publishers and Subscribers over an interface</a></h3>
<p>
If you have multiple implementations of an interface (for example a plug-in), you can define on the interface itself,
which events or event handler methods should by used. This allows you to define the interaction with the event broker once on the interface for all implementations.
</p>
<h3><a href="eventbrokerregistrationbyregistrar.html">Registration of Publishers and Subscribers by Event Broker Registrar</a></h3>
<p>
Due to the fact that values used by an attribute have to be compile time constant,
you can fallback to the registration by the event broker registrar in more advanced cases.
This gives you full flexibility how you register events and event handler methods on the event broker.
You can even register events and handler methods of external classes, without having to write any decoration code.
</p>
<h3><a href="eventbrokersimplifiedhandlermethods.html">Simplified Handler Methods</a></h3>
<p>
When you are not interested in the <code>sender</code> argument, or want to directly access the value of a <code>EventArgs<T></code> then simplified handler methods are for you.
</p>
<h3><a href="eventbrokerdirectinteraction.html">Direct Event Broker Interaction</a></h3>
<p>
In cases where it does not make sense to register an instance on the event broker, you can directly fire events onto the event broker without a publisher.
This is for example very useful with scheduled tasks. These tasks are created to perform some task and are then garbage collected.
Therefore it would be overkill to register the tasks as a publisher, fire the event and then unregister the task and collect it.
</p>
<h3><a href="eventbrokerhandlers.html">Event Broker Handlers</a></h3>
<p>
Handlers a responsible for executing a handler method of a subscriber.
There are built-in handlers for executing on the same thread as the event was fired, on a background thread, on the user interface thread synchronously and
on the user interface thread asynchronously.
</p>
<p>
You can provide your own handler to control execution in additional ways.
</p>
<h3><a href="eventbrokermatchers.html">Matchers</a></h3>
<p>
Matchers can be used to take control of the routing of events. A matcher can prevent that an event is passed to a certain subscriber.
An example of this is, that an event that can be canceled is passed to further subscribers when it is already canceled.
Or an event should only be passed to a subscriber matching a certain criteria.
</p>
<h3><a href="eventbrokerexceptionhandling.html">Exception Handling</a></h3>
<p>
The publisher of an event most likely does not know what to do with an exception thrown by a subscriber. This is a result of the decoupling.
Therefore, the event broker gives you the possibility to take control of the exception handling by using extensions.
</p>
<h3><a href="eventbrokerextensions.html">Extensions</a></h3>
<p>
You can use extensions to add functionality to the event broker.
Examples are the DistributedEventBroker (sending events over process boundaries) and MappingEventBroker (mapping event arguments to other types) extensions.
Extensions can also be used to implement logging or take control of exception handling.
</p>
<h3><a href="eventbrokerlogging.html">Logging</a></h3>
<p>
Logging is implemented with an extension. In the SourceTemplates package there is a sample logger for log4net.
You can easy write your own logging mechanism by writing an extension.
</p>
<h3><a href="eventbrokertestability.html">Testability</a></h3>
<p>
Testing multi-threaded, loosly coupled systems is a big challange.
Therefore the event broker supports you by providing infrastructure to make execution of events always synchronous.
There is no need for using signals or locks in your unit tests.
</p>