EventBroker Extension

The EventBroker Extension (EB) consists of two parts which may be used individually: A Generic Mediator and a per request based Event Broker. The latter is complete with an event broker strategy and sanity check for your web application at application Start.

The smart client world is as we all know different from our world which is request based with instances of pages living only through one request on the application server. In order for web applications to reach better UI composability a lightweight event broker system can be used. The EventBroker is such an extension.

Publish - Subscribe support

In order for any UI composability to be possible the notion of Publications and Subscriptions is very useful. EB supports two attributes for this purpose: EventPublicationAttribute and EventSubscriptionAttribute. The former will decorate any events you wish to publish from one type to another. The latter will decorate any method handlers which are interested in subscribing to an event. The attributes are topic based so any pub-sub pair is considered joint if their string topic match.

Design impacts

Publishing through events is the familiar way to announce to the world that something has happened. Subscribing using the familiar event handler method signature is the normal way of becoming aware of an event.

EventHandler FooEvent;

void myFooHandler(object sender, EventArgs e)
{
    [...]
}


The design improved some with the introduction of the generic event handler which turned the situation into this (using the fictive data class Person):

EventHandler<DataEventArgs<Person>> FooEvent;

void myFooHandler(object sender, DataEventArgs<Person> e)
{
    [...]
   Person p = e.Data;
}


However in many cases the subscriber only wants notification and is completely uninterested in the data portion of the event. The subscriber may also be uninterested in the sender of the event. Therefore the EB supports several additional subscribing handler signatures:

[EventPublication("Foo")]
EventHandler<DataEventArgs<Person>> FooEvent;


Has these possible subscribers:

 [EventSubscription("Foo")]
void myFooHandler(object sender, EventArgs e) // Has to cast e back to DataEventArgs<Person>.

[EventSubscription("Foo")]
void myFooHandlerGeneric(object sender, DataEventArgs<Person> e) // Exact match to the generic data type sent.

[EventSubscription("Foo")]
void myFooMethod(Person p) // Alternate signature which does not care about the sender and gets the data sent extracted and ready

[EventSubscription("Foo")]
void myFooNotification() // Notification method which does not care about the sender or the data sent.


The main gain in the approach to let the EB handle many types of subscribers is that you may design your applications subscribers for their intended use.

Note: The following is also supported and does impose an implementation constriction on the DataEventArgs!

(Using another fictive class Address)

[EventPublication("Bar")]
EventHandler<DataEventArgs<Person, Address, Person>> BarEvent;

[EventSubscription("Bar")]
void myBarMethod(Person p1, Address a, Person p2)


The property getters on the DataEventArgs<Person, Address, Person> must be defined in the same order as the generic arguments:

interface DataEventArgs<S, T, U>
{
   S SData {get;}
   T TData {get;}
   U UData {get;}
}



The names of property members are not important but the order is critical since the EB mechanism for extracting data from the generic DataEventArg carrier cannot make assumptions on how to forward the data to a subscribing method.

Generic Mediator

If a full event broker is not useful for your project perhaps a generic mediator is more suitable? The generic Mediator takes two types and mediates events and methods between them.

interface IA
{
   [EventPublication("Foo")]
   event EventHandler<DataEventArgs<Person>> Foo;
}


interface IB
{
   [EventSubscription("Foo")]
   OnFoo(Person person);
}

A a = new A();
B b = new B();

// This mediator will mediate the Foo event from a to b.
Mediator<IA, IB> m = new Mediator(a ,b);


Event Broker functionality

There are four steps to using the EB. One is from the design time of your application and the other three are functional prerequisites to active the use of the EB inside your project:
  1. Publish and Subscribe your events and handlers using the attributes above. (This is the design time step.)
  2. Add the EventBrokerStrategy to the ObjectBuilder.
  3. Instantiate a ReqestEventBroker before page execute (PrePageExecute). Also dispose it after page execute (PostPageExecute).
  4. Perform an application start sanity check (EventBrokerStrategy.ApplicationPubSubSanityCheck).

Publish and Subscribe

This step is part of your code design and the flow of control through your composable application. Add the EventPublicationAttribute to your publishing events and the EventSubscriptionAttribute to your subscribing methods.

EventBrokerStrategy

Add the EventBrokerStrategy to your builder's post initialization BuilderStage:

Strategies.AddNew<EventBrokerStrategy>(WCSFBuilderStage.PostInitialization);

RequestEventBroker

Create a new instance of the RequestEventBroker per page request:

protected override void PrePageExecute(Page page)
{
	RequestEventBroker.ResetEventBroker();
}


Dispose it after the page execute:

protected override void PostPageExecute(Page page)
{
	RequestEventBroker.Instance.Dispose();
}


The Instance is stored in the user session.

Application Sanity Check

Before the application starts run the sanity check:

protected override void Start()
{
	EventBrokerStrategy.ApplicationPubSubSanityCheck(RootContainer.Services.Get<IModuleEnumerator>());
}


The purpose of this check is twofold:
  • To perform the type inspection once for the publishers and subscribers.
  • To make sure your implementers have not published a topic and subscribed the same topic with a method that cannot be used for subscription of that publishers signature.

If sanity check is not performed this will throw a runtime EventHookupException:

[EventPublication("Foo")]
event EventHandler<DataEventArgs<Person>> Foo;

[EventSubscription("Foo")]
OnFoo(string name);


OnFoo cannot be invoked with the parameter Person - it expects a string parameter. ApplicationPubSubSanityCheck catches this problem at application start and throws the EventHookupException with detailed explanation.

Last edited Oct 29, 2007 at 5:36 AM by gblock, version 1

Comments

No comments yet.