Eventing In WCF
Let's start with the simple part - the usage.
The eventing is built on the idea of a bus (i.e. no centralized components) and the resources/services that want to use eventing have to use a library which I call EventBroker. There are two modes for using the EventBroker. one is "regular" events which are contexless. This means that consecutive events can reach different services, and there is no context that flows from event to event:
bool raisedEvent = eb.RaiseEvent<SampleEvent>(new SampleEvent());
The second type of events are Sagas, which represent long running interactions. Sagas does have a "best effort" guarantee to reach the same recipients over consecutive calls. Also you can also End sagas (sucessful termination), Force End Saga (successful termination by a service that didn't initiate the saga) and Abot Saga (unsuccessful termination): Here is how you raise a saga event.
var evnt = new SampleEvent { data = somevalue};
var SagaId = Guid.NewGuid();
eb.RaiseSagaEvent<SampleEvent>(SagaId, evnt);if
you use the same Saga Id, the events are handled as part of the same
saga, if you use a Saga Id that wasn't previously defined it will
initialize a new saga.The eventbroker translates events to the relevant contract and
dispatches the events over to the different subscribers. Which brings
us to to the next part which I guess, is also a little more
interesting. How subscriptions are defined.
The first thing to do is to define the event itself.
public class SampleClassEvent :ImEvent
{
public string DataMember1 {set;get;}
public int DataMember2 { set; get;}
}
There
aren't any real constraints on the event, except that it has to
"implement" the ImEvent interface. Which is really an empty interface
but it marks the event as one for the event broker.
Then you have to define an interface for handling the event. The event
broker, builds on the idea of convention rather than configuration (an
idea popularized by the rails framework) so it is easier to generate
the interface (something I do with a resharper template)
[ServiceContract]
public interface IHandleSampleClass
{
[OperationContract]
int SampleClass(SampleClassEvent eventOccured);
}
The
convention is that the interface will have a IHandle prefix followed by
the name of the event. It will hold a single operation named like the
event (without the Event suffix) and will recieve a single parameter
which is the event data. Currently events do return a value (int) but
I am thinking about changing it to void and have everything marked as
OneWay for added performance
Now, when we create a service which needs to handle events it will do that by specifing which events it handles. E.g.
[ServiceContract]
public interface ImSampelResource : ImContract, IHandleSampleClass, IHandleSomeOtherThing
{
}
So each contract declares all its subscriptions (by a list
of IHandleXXX). It should also include the ImContract interface which
holds all the service operation used by the eventbroker (e.g. ending
sagas etc.).
Services that want to raise events should inherit from a ControlEdge class (base class Edge component that delegates control events to the event broker)
There's still the question of how does the event broker knows where to
find other services. There are several ways this can be done (e.g. a
service repository) but since we have blogjecting watchdogs in place
anyway, we use them to propagate liveliness (and location ) of services.
This sums up this post. It is basically just a little context for
several planned posts where I hope to talk about some of the
challenges, alternatives and design decisions that led me to the
current design. Meanwhile, I'd also be happy to hear any comments,
ideas or reactions you may have.
VP R&D of xsights (www.xsights.com) Arnon Rotem Gal-Oz has more than 19 years of experience managing, architecting and building large scale, mission critical, distributed systems. Before joining XSIGHTS, Arnon worked as the development manager of the Biometrics line in Rafael. Prior to that, he worked in various technical and managerial roles in large corporations including Microsoft, Amdocs and Matrix. Arnon is a DZone MVB and is not an employee of DZone and has posted 26 posts at DZone.
- Login or register to post comments
- 1316 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)









