Using the Flex Singleton register Pt 2/3 (Overriding Flex implementations)

This is the second in a 3 parter about the flex singleton register. This post will look at how to register your own classes with the Singleton register so you can actually use your custom implementations instead of the Flex default implementations.

The first post on the Singleton register can be found here


Registering custom implementations - the problem The last post showed that you simply use:


Singleton.registerClass("mx.managers::IPopUpManager", mx.managers.PopUpManagerImpl);  

So, in theory you just add in your own class. The problem is the Singleton.registerClass method works on a first come first serve basis - once a class is registered against an interface, no subsequent classes can be registered.

All the Flex default implementations are registered as the framework is initialized (in SystemManager.mx_internal::docFrameHandle). So, there is no chance for you to register your own implementation.


Registering custom implementations - the solution Create a custom preloader for the main Flex application. If you define your own preloader, you can register classes BEFORE the SystemManager registers the Flex classes.

 
<mx:Application  	xmlns:mx="http://www.adobe.com/2006/mxml" 	preloader="com.myDomain.preloaders.ApplicationPreloader" 	> 

And then in your preloader...

package com.myDomain.preloaders 
 { 
    import mx.core.Singleton; 
    import mx.preloaders.DownloadProgressBar; 
 
    public class ApplicationPreloader extends DownloadProgressBar
    { 
        private static var classConstructed:Boolean = staticInitializer();

        private static function staticInitializer():Boolean 		{         
            Singleton.registerClass("mx.managers::IPopUpManager",    
            com.myDomain.managers.MyCustomPopUpManagerImpl);  			 			return true; 
        } 
    } 
 }

And now we have registered our implementations before Flex does!

To tidy things up you could have a static class that does all the reigstration, and in this preloader simply call com.myDomain.manager.SingletonImplManager.register();.

The next post will look at using all this with a transparent modal background for Air applications.

Using the Flex Singleton register Pt 1/3

This is the first in a 3 part post about using the Flex Singleton register. This post will deal with what the Flex Singleton register is as well as how and why its used. The second will look at how to register your own classes with the Singleton register (not as easy as it sounds) and the third will be a real life example.

The final post will show you how to give the Alert control the ability to create a modal overlay that supports a custom chrome in Adobe Air. The big pain with a custom chrome (say a splat shape) is that the modal overlay covers the entire bounds of the window - including any transparent areas. So for irregular shapes/chrome - like a splat as a background, you get a big square slapped over the top - not ideal. What you want is ONLY the splat to be overlaid with the modal background.

By using the Singleton register and a custom implementation of the PopupManager we can add this functionality without having to create a custom Alert class. You don't have to change any of your existing app code where Alerts are used, all existing calls to Alert will now have our new and improved modal background!


The Singleton register

Flex has many singletons that are used as the default functionality for its components - the popup manager being one of them. At start up, the default implementations that flex uses are registered with the static class Singleton. When a class such as the PopupManager is first used, it will retrieve the class that defines its core functionality from the Singleton class.

The classes are registered against an interface, and it is by the interface that they are retrieved. Thus any class implementing the correct interface could be registered and used instead of the default class.

The ability to define custom implementations is a great feature of the flex framework, but is largely undocumented and support for actually overriding the default implementations is greatly lacking. However, it can be done!


Retrieving a class from the register

The PopupManager class is simply a Static class, that upon first use, will retrieve a singleton object that defines its core functionality.

Below is how the PopupManager retrieves the singleton that it will use for its core functionality. This is a static method in the PopupManager.

 
private static function get impl():IPopUpManager 
{ 
    if (!_impl) 
    { 
        _impl = IPopUpManager( 		Singleton.getInstance("mx.managers::IPopUpManager"); 
    } 

    return _impl; 
} 

The key line is :

 
Singleton.getInstance("mx.managers::IPopUpManager") 

This will perform a look up on the static class Singleton for a class that has been registered against the interface mx.managers::IPopUpManager.

If one is found, its static getInstance method is called and the instantiated singleton is returned. This instance is then used as the implementation of the PopupManagers core functionality. So, if you could register your own class against mx.managers::IPopUpManager, you could completely change how the PopupManager works!
Registering a class with the Singleton register

When the flex framework initializes, it registers each of these implementations with the static class Singleton. This simply adds the class to a class map, indexed by the interface name that it implements.

The class that is registered must adhere to the following 2 points.

  1. It must implement the interface it is registered against.
  2. It must implement a static method getInstance that returns the singleton instance of itself.


In the case of the PopupManager, the singleton class that is registered is mx.managers.PopUpManagerImpl. Its is registered against, and implements the interface mx.managers.IPopUpManager and it contains a static method getInstance as below...

 
 public static function getInstance():IPopUpManager 
 { 
    if (!instance)             instance = new PopUpManagerImpl(); 
    return instance; 
 } 
 

The registration is on a first come first serve basis, so the first class to be registered against a particular interface is stored in the Singleton registry. Any subsequent registrations for the same interface are ignored.

The PopupManger will be registered like this...

 
Singleton.registerClass("mx.managers::IPopUpManager", mx.managers.PopUpManagerImpl); 


Custom registration..... The drawback is, that all the classes are registered by the time the Flex framework has initialized, and as the register is on a first come first serve basis any subsequent registrations would be ignored.

The next post will show you how to register your own implementations before the Flex classes are registered.