Loosely coupled eventing in Silverlight 2.0 - part 2

In the last post we introduced the general problem statement that we were trying to solve, and we started digging in to the actual implementation of the eventing framework.  This post will continue where the previous one left off (it wouldn't be logical if it didn't would it?! *grin*) and we'll dig into the event manager a little more, and some of the pre-requisite coding styles you'll be adopted to utilise this eventing infrastructure.

EventManager
The EventManager class is basically an implementation of the classic observer pattern, with a few extra smarts.  When you construct an instance of a type, say a user control, an extension method (Register in this case) gets called.  The end result is that the EventManager will reflect against the type instance pulling out all the methods that have been decorated with the custom [EventListener(...)] attribute.  These methods are then stored in a generic Dictionary against a known key, where the key is the URI of the method as provided by the [EventListener(...)] attribute.  By way of an example, here's a sample from the supplied solution file that you can download:

[EventListener( "local://TestEvent", 1 )]

This forms the basis of the publication-subscription model that we're going to be using.  I would recommend that you stick with some URI type scheme as they're easy to understand, you can make them map against whatever takes your fancy.  The second part of the [EventListener(...)] attribute assigns a priority to this method on some arbitrary scale from 1 to n.  What the priority does is allow you to primitively schedule the order in which you fire methods, so if you have things that are time critical you can assign them a higher priority than other methods that respond to the same event URI.  However, if you aren't bothered by priority you can just accept the default condition which is priority 1.  These different attribute constructors are described in the solution if you have further questions.

**Note that in the current implementation of this framework events are executed serially based on their order of priority in the event collection 1 being the highest, n being the lowest, we will be adding additional switches to asynchronously dispatch methods using the background threading feature that has recently been added to Silverlight 2.0 Beta 1.

Your classes - event subscribers
By and large you won't have to worry about any of the EventManager internals other than when you are creating your own classes and we intentionally kept the number of things you as a developer have to do to make this work as limited as possible in scope.  Here's an example UserControl that we will be using as an event subscriber, as is typical for a UserControl in Silverlight 2.0, it consists of a XAML document describing the visual elements, and a code behind file that is associated with it containing its implementation:

<UserControl x:Class="DesignTek.Silverlight.SimpleListenerControl1"
   xmlns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="200">
    <Grid x:Name="LayoutRoot" Background="Green">
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock x:Name="EventListener" Text="I'm an event listener" FontFamily="Arial" FontSize="18" Foreground="White" HorizontalAlignment="Center"/>
        </StackPanel>
    </Grid>
</UserControl>

Nothing in the XAML is out of the ordinary from what you would usually create using Expression Blend, or Visual Studio 2008.  Where it gets more interesting is in the code behind for this usercontrol:

[SecuritySafeCritical]
public partial class SimpleListenerControl1 : UserControl
{
    public SimpleListenerControl1()
    {
        InitializeComponent();
        this.Register();
    }
    [EventListener( "local://TestEvent", 1 )]       
    public string EventMethod( object sender, EventArgs e )
    {
        ...
    }
}

There are two things to note in this code example. The first is this attribute [SecuritySafeCritical]. This is required for reasons of code access security.  As Silverlight has moved from an Alpha preview to Beta, Microsoft have been gradually tightening up the security constraints around executing code using things like reflection with good reason.  This unfortunately means that we have to declare that this type is "ok" to call methods on.  Also note that unlike in the 2.0 Alpha where everything was intrinsically marked [SecuritySafeTransparent], you cannot call private methods any longer even though you can successfully discover them using reflection.  This is a minor irritation though.

The second thing to note is the method "this.Register()" in the constructor of the usercontrol.  This is where the extension methods we mentioned previously come into play and you will find that Visual Studio 2008 will give you the Intellisense for them wherever the type you are dealing with derives from Control.  What this method does is take the current type instance and pass it off to the EventManager, who then scours the type looking for methods decorated with the [EventListener(...)] attribute.  So that's all you need to do to get your type to play with the eventing system! We were having a philosophical debate on whether to hide this behind a base class and do it automagically, but in the end we decided it would be better if it was an opt-in scenario.

In the third and final post, we'll discuss setting up event publishers, showing you a demonstration application and giving you the download location for the framework from Codeplex!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Related posts

Add comment


 

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 21. 2008 08:27