Thursday, November 15, 2012

Raise events properly


Don't raise an event just by "calling" it. You'll get NullReferenceException when there are no subscribers. Surprise!
Instead, you should check for null before trying to invoke the delegate:
if ( MyEvent != null ) MyEvent( this, EventArgs.Empty );
But that's also not good enough: in a multithreaded application, the last subscriber might unsubscribe from the event between the null check and the calling point, rendering the variable null and causing same old NullReferenceException.

To safeguard from that, one should cache the value in a local variable first:

var ev = MyEvent;
if ( ev != null ) ev( ... );

I have also found it useful to have an extension method for this case:
public static void Raise ( this EventHandler h, object sender )
{
    if ( h != null) h( sender, EventArgs.Empty );
}
And then:
MyEvent.Raise ( this );

And also add the generic case:
public static void Raise<T>( this EventHandler<T> h, object sender, T args )
   where T : EventArgs
{
    if ( h != null) h( sender, args );
}

What's AMD and why you need it

Here is a little AMD 101.
AMD, by the way, stands for Asynchronous Module Definition, so saying "AMD module" is a bit of a RAS syndrome, but everybody does it anyway.

First, let's define the problem. Say you're developing a Web application with a fair amount of client side functionality. Or, perhaps, a totally client side application. When your Javascript code is more than "hello world", you may want to split it into several components and, perhaps, multiple files (you know, just for the sake of mental health). Further, you may want to develop some of those components independently as a library. Or, perhaps, you want to use a library that somebody else already developed for you. And then those libraries may want to use other libraries, and so on. You know, very much the way you build other, non-Javascript applications.
But here is the problem: how do you know which Javascript files to include in your page? Obviously, the libraries must have some way of specifying which files they need, and these specifications must propagate from the deepest layers of the libraries all the way to the top. This problem can be solved with some trickery, but... But that's only half of the problem. The other half - correct order. How do you ensure that the browser doesn't execute a particular script until all its dependencies are loaded? And with the internet being asynchronous and all, the order of loading can be anything.

So you must create sort of a dependency graph of all the libraries, and only then go about loading them in the correct order.


A piece of software that does this graph thing is called an "AMD loader".


There are many of those available. The one I'm using is called RequireJS. But they all, thank the great open source community, have the exact same standard API.


Here is how it works.

The AMD loader provides two functions: "define" and "require".


The "define" function defines a module. Every time you call it, the AMD loader knows: "aha, here is another module". The first argument of define() is an array that contains names of modules that the module being defined depends upon. The second argument is a function that gets called once all the dependencies are loaded, and the arguments passed to that function will be the values exported from those dependencies, in the same order. The return value of that function is the value that this module wants to export.

 define ( ["jQuery"], function ($) {
   // the module code goes here
   return "my exported value";
 });


The require() method works almost exactly the same, except the function doesn't return anything. The require() call is the "top level" of the module hierarchy.