Mxml based dependency injection for Flex
Rather than emulating existing dependency injection frameworks, Flicc has been built from the ground up to work with Flex. Flicc works with the existing Flex event model to allow you to easily inject objects on to Mxml components without having to pass factory references around your application or introduce global state, as well as working well with modular applications. Flicc also makes use of the dynamic features of Actionscript 3.0 to keep factory configuration as small as possible with minimal boiler-plate.
If you have any questions regarding Flicc or have any feedback or suggestions then please get in touch at mike dot herron at talk21 dot com.
Tutorial
The tutorial here is also available as part of the Full Download. The samples referenced throughout are available as part of the full download as both source code and executable SWFs with View Source ability.
- The Basics
- Defining Configuration
- Referencing Objects
- Single Instances
- Injecting Lists
- Constructor Arguments
- Initialise and Destroy
- Object Place Holders
- Event Handlers
- Splitting Up Configuration
- Using Flicc With Modules
1. The Basics
1.1. Creating a Factory
Like most Dependency Injection frameworks, Flicc is based around two main components: a configuration
that defines one or more objects along with their dependencies, and a factory that creates
objects (or configures existing objects) based on this configuration. In Flicc, the
MxmlObjectFactoryConfig class is used to define configuration and the MxmlObjectFactory
is used to create or configure objects.
As their names suggest, the MxmlObjectFactoryConfig and MxmlObjectFactory
classes are designed to be used as tags in an MXML document. The below example shows how a factory
configuration, Config, is created by extending the MxmlObjectFactoryConfig and
populating the descriptors element.
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Object objectId="welcomeModel" clazz="{ SimpleWelcomeModel }">
<message>Hello World</message>
</Object>
</descriptors>
</MxmlFactoryConfig>
The configuration is then passed to an instance of MxmlObjectFactory on the
main application:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="flicc.factory.mxml.*"
xmlns:sample1="sample1.*"
creationComplete="init()">
<flicc:MxmlObjectFactory id="factory">
<sample1:Config />
</flicc:MxmlObjectFactory>
<sample1:WelcomeComponent factory="{ factory }"/>
</mx:Application>
The configuration in this example describes a single object of type SimpleWelcomeModel
with the unique identifier of welcomeModel. The child element, <message> is set to
Hello World - this is how dependencies are expressed in Flicc. When the factory creates this
object, it will set the message property on SimpleWelcomeModel to Hello World.
Now that the factory has been configured, it's possible to create objects using the getInstance
method. The custom component, WelcomeComponent, uses the factory to create an
instance of SimpleWelcomeModel:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net"
creationComplete="init()">
<mx:Script>
<![CDATA[
import flicc.factory.IObjectFactory;
public var factory : IObjectFactory;
[Bindable]
public var welcomeModel : IWelcomeModel;
public function init() : void
{
welcomeModel = factory.getInstance( "welcomeModel" );
}
]]>
</mx:Script>
<mx:Label text="{ welcomeModel.message }" />
</mx:VBox>
1.2. Configuring Mxml Components
Rather than passing factory instances around your application, you can use the Configure
tag along with the FliccListener to inject objects on to MXML components. Firstly, wrap
a FliccListener around the factory:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net"
xmlns:sample="configuringcomponents.*">
<flicc:FliccListener>
<flicc:MxmlObjectFactory>
<sample:Config />
</flicc:MxmlObjectFactory>
</flicc:FliccListener>
<sample:WelcomeComponent id="helloWorld" />
</mx:Application>
Then, add the Configure tag to the component you want to configure
using the factory:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net">
<flicc:Configure />
<mx:Script>
<![CDATA[
[Bindable]
public var welcomeModel : IWelcomeModel;
]]>
</mx:Script>
<mx:Label text="{ welcomeModel.message }" />
</mx:VBox>
Finally, add a Component tag to the factory configuration with an
objectId matching the Flex id of the component that defines
what objects you want to inject:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Component objectId="helloWorld">
<welcomeModel>
<Object clazz="{ SimpleWelcomeModel }">
<message>Hello World</message>
</Object>
</welcomeModel>
</Component>
</descriptors>
</MxmlFactoryConfig>
So how does this work? When the WelcomeComponent's creationComplete event fires,
the Configure tag dispatches a FliccEvent.CONFIGURE event that bubbles up the
display object hierarchy. The FliccEvent contains 2 properties - objectId and
target. By default, the Configure tag sets the target to the
component that it was declared on, and the objectId to the flex id of the
component. The FliccListener will capture this event and make a call to
MxmlObjectFactory.configure using the objectId and target from the
FliccEvent as arguments. The configure method will then look for a descriptor matching
the provided objectId, and apply the described dependencies to target.
In this case, there is a Component element has been declared with an objectId
that matches the id of the WelcomeComponent - so the welcomeModel
property will be set to an instance of SimpleWelcomeModel. (Note that Component
is just an Object element that has no clazz defined - it can be used instead
of Object to more clearly signal intent)
This method is far more flexible than the previous method. Firstly, there's no need pass instances of
MxmlObjectFactory to every component in the application. Secondly, objectId's
don't need to be hardcoded within components, making them far easier to reuse. For example, using the
Configure tag, another instance of the WelcomeComponent can be declared and
configured to display a different message:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net"
xmlns:sample="configuringcomponentss.*">
<flicc:FliccListener>
<flicc:MxmlObjectFactory>
<gettingstarted:Config />
</flicc:MxmlObjectFactory>
</flicc:FliccListener>
<sample:WelcomeComponent id="helloWorld" />
<sample:WelcomeComponent id="goodbyeWorld" />
</mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Component objectId="helloWorld">
<welcomeModel>
<Object clazz="{ SimpleWelcomeModel }">
<message>Hello World</message>
</Object>
</welcomeModel>
</Component>
<Component objectId="goodbyeWorld">
<welcomeModel>
<Object clazz="{ SimpleWelcomeModel }">
<message>Good Bye World</message>
</Object>
</welcomeModel>
</Component>
</descriptors>
</MxmlFactoryConfig>
The code for the WelcomeComponent doesn't change - all that's required is
a new Component definition in the factory configuration. Using the
Configure tag also means that you don't have Flicc references littered throughout
your code base, just a single MMXML tag where required - Actionscript classes in your
application aren't aware of Flicc at all, making unit testing and reuse a lot easier.
1.3. Configure Tag Options
The Configure tag can be customised in several ways.
The target property can be set to configure a component other than the one the
tag was declared on. This is useful when you want to configure a component whose source code you
don't have direct access to, or a component you want to be able to package and reuse across projects
and therefore not have direct references to Flicc. The below example shows how a DateField
component can be configured by specifying the target property on the
Configure tag.
<flicc:Configure target="{ selectDate }" />
<mx:DateField id="selectDate" />
The id property of the target must still map to a Component
configuration element:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Component objectId="selectDate">
<formatString>DD-MM-YYYY</formatString>
<selectedDate>{ new Date() }</selectedDate>
</Component>
</descriptors>
</MxmlFactoryConfig>
The objectId property can be set to configure a component with a hardcoded ID rather
than relying on the declared Flex id of the component. Sometimes this is nessecary when
more than one component in the same scope must be configured using the same Component
definition:
<flicc:Configure target="{label1}"
objectId="label" />
<flicc:Configure target="{label2}"
objectId="label" />
<mx:Label id="label1" />
<mx:Label id="label2" />
Finally, the trigger property can be set to define what event the Configure
tag listens for before dispatching the FliccEvent. By default the Configure
tag uses creationComplete, but you might want to wait until the show
event before configuring a component for performance reasons:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net"
visible="false">
<flicc:Configure target="{hiddenLabel}" trigger="show" />
<mx:Label id="hiddenLabel" />
</mx:VBox>
Remember that the Configure will always listen for the trigger
event on the component it is declared on, not the target.
2. Defining Configuration
2.1. Referencing Objects
You can include references to other objects within the configuration by using the Ref
element. The to property must match the objectId of another object within the same
configuration:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Component objectId="goodbyeWorld">
<welcomeModel><Ref to="GoodbyeModel" /></welcomeModel>
</Component>
<Object objectId="GoodbyeModel" clazz="{ SimpleWelcomeModel } ">
<message>Good Bye World</message>
</Object>
</descriptors>
</MxmlFactoryConfig>
2.2. Single Instances
By default, each object created by the factory will be cached and reused based on the
objectId. To create a new instance whenever the object is required, set the
isSingleton property on Object to false:
<Object objectId="GoodbyeModel" clazz="{ SimpleWelcomeModel } " isSingleton="false">
<message>Good Bye World</message>
</Object>
To have the factory create all singleton objects at application start up, set the
preInstantiateSingletons property to true:
<flicc:MxmlObjectFactory id="factory">
<sample1:Config preInstantiateSingletons="true"/>
</flicc:MxmlObjectFactory>
2.3. Injecting Lists
The List element can be used to describe IList implementations or
Arrays. The elements will be added to the list in the order they appear in the
configuration. List provides an instance of the ArrayCollection class
if the clazz property is not specified:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component objectId="randomWelcome">
<welcomeModel>
<Object clazz="{ RandomWelcomeMessage }">
<messages><Ref to="messages" /></messages>
</Object>
</welcomeModel>
</Component>
<List objectId="messages">
<mx:String>Hey World</mx:String>
<mx:String>How are things World?</mx:String>
<mx:String>Hello World</mx:String>
<mx:String>Nice to see you, World</mx:String>
<mx:String>Go away World!</mx:String>
</List>
</descriptors>
</MxmlFactoryConfig>
List config elements can contain other Objects, Ref
elements, and "primitive" types like String and Number. If the
List contains primitive types only, the SimpleList element can be used to write
this as a comma seperated string:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component objectId="randomWelcome">
<welcomeModel>
<Object clazz="{ RandomWelcomeMessage }">
<messages><Ref to="messages" /></messages>
</Object>
</welcomeModel>
</Component>
<SimpleList objectId="messages">
Hey World, How are things World?, Hello World,Nice to see you, World,Go away World!
</SimpleList>
</descriptors>
</MxmlFactoryConfig>
Note that any whitespace before and after each value will be trimmed.
2.4. Constructor Arguments
Constructor arguments can be passed using the constructor property on Object. The arguments are passed in the order they are defined in the configuration:
<Object clazz="{ RandomWelcomeMessage }" objectId="randomMessage">
<constructor>
<Ref to="messages" />
</constructor>
</Object>
<SimpleList objectId="messages">
Hey World, How are things World?, Hello World,Nice to see you, World,Go away World!
</SimpleList>
You can pass up to 10 arguments to a constructor in Flicc.
2.5. Initialise and Destroy
You can specify a method for Flicc to invoke once it has fully instantiated an
object and satisfied it's dependencies using the initialiseMethod
property:
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net">
<descriptors>
<Component objectId="helloWorld">
<welcomeModel>
<Object clazz="{ SimpleWelcomeModel }" initialiseMethod="init" />
</welcomeModel>
</Component>
</descriptors>
</MxmlFactoryConfig>
package initanddestroy
{
public class SimpleWelcomeModel
{
private var _message : String;
public function get message() : String
{
return _message;
}
public function init() : void
{
_message = "Init method called on SimpleWelcomeModel";
}
}
The initialiseMethod must take no arguments. You can also specify
a destroyMethod which Flicc should call when the factory that created
the object is destroyed - see the section on Modules for more details.
2.6. Object Place Holders
Since Mxml is already very adept at declaratively instantiating objects,
you can use the ObjectPlaceHolder tag to write an Mxml component declaration within the
factory when there are no other references you wish to inject on to the object. This is useful
for injecting RPC classes for example:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:rpc="mx.rpc.http.*">
<descriptors>
<Component objectId="welcome">
<welcomeModel><Ref to="httpMessage" /></welcomeModel>
</Component>
<Object clazz="{ HttpWelcomeModel }" objectId="httpMessage">
<constructor>
<Ref to="messageService" />
</constructor>
</Object>
<ObjectPlaceHolder objectId="messageService">
<rpc:HTTPService url="message.xml"
resultFormat="e4x"/>
</ObjectPlaceHolder>
</descriptors>
</MxmlFactoryConfig>
Creating objects directly using ObjectPlaceHolder provides a greater degree of compile-time
type checking.
2.7. Event Handlers
The handlers element can be used to listen to an event from another factory Object
or a property on the target class. In the below sample, the IWelcomeModel
implementation listens for the NAME_CHANGED event on the INameModel
implementation:
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net">
<flicc:Configure />
<mx:Script>
<![CDATA[
import eventlisteners.INameModel;
import eventlisteners.IWelcomeModel;
[Bindable]
public var nameModel : INameModel;
[Bindable]
public var welcomeModel : IWelcomeModel;
]]>
</mx:Script>
<mx:FormItem label="Name">
<mx:TextInput id="nameInput" text="{ nameModel.name }"
change="nameModel.name = nameInput.text" />
</mx:FormItem>
<mx:FormItem>
<mx:Label text="{ welcomeModel.message }" />
</mx:FormItem>
</mx:Form>
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component objectId="nameForm">
<nameModel>
<Ref to="nameModel" />
</nameModel>
<welcomeModel>
<Ref to="welcomeModel" />
</welcomeModel>
</Component>
<Object objectId="nameModel" clazz="{ EventDispatchingNameModel }" />
<Object objectId="welcomeModel" clazz="{ SimpleWelcomeModel }">
<handlers>
<EventHandler>
<eventName>{ NameModelEvent.NAME_CHANGED }</eventName>
<handler>handleNameChanged</handler>
<source><Ref to="nameModel" /></source>
</EventHandler>
</handlers>
</Object>
</descriptors>
</MxmlFactoryConfig>
package sample8
{
import flash.events.EventDispatcher;
public class EventDispatchingNameModel extends EventDispatcher implements INameModel
{
private var _name : String;
public function get name() : String
{
return _name;
}
public function set name( value : String ) : void
{
_name = value;
dispatchEvent( new NameModelEvent( value ) );
}
}
}
package sample8
{
public class SimpleWelcomeModel implements IWelcomeModel
{
private var _message : String;
public function set message( value : String ) : void
{
_message = value;
}
[Bindable]
public function get message() : String
{
return _message;
}
public function handleNameChanged( event : NameModelEvent ) : void
{
message = "Hello " + event.name;
}
}
}
To listen to an event from a member variable rather than another object, set the source
property to the name of the member rather than using the Ref element. So in the above
example, if the WelcomeModel contained an instance of the
EventDispatchingNameModel on a member variabled called name,
then source would be set to name.
2.8. Splitting Up Configuration
The factory configuration can be divided in to several smaller configuration classes using the
externalDescriptors property on MxmlFactoryConfiguration. The top level
configuration class must still extend MxmlFactoryConfig with the child configuration
elements extending MxmlDescriptors:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:splittingupconfig="splittingupconfig.*">
<externalDescriptors>
<splittingupconfig:ListConfig />
</externalDescriptors>
<descriptors>
<Component objectId="randomWelcome">
<welcomeModel>
<Object clazz="{ RandomWelcomeMessage }">
<messages><Ref to="messages" /></messages>
</Object>
</welcomeModel>
</Component>
</descriptors>
</MxmlFactoryConfig>
<?xml version="1.0" encoding="utf-8"?>
<MxmlObjectDescriptors xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<SimpleList objectId="messages">
Hey World, How are things World?, Hello World,Nice to see you, World,Go away World!
</SimpleList>
</descriptors>
</MxmlObjectDescriptors>
Child MxmlObjectDescriptors may contain other MxmlDescriptors
referenced through the externalDescriptors element and so on.
3. Using Flicc with Modules
3.1. Configuring Modules
You can include Configure tags on components loaded as part of a
Module and Flicc will treat them just as it would any other component in
the display hierarchy. Taking advantage of this, you can load Modules and
use the parent Applictions MxmlObjectFactory to configure the
Modules components. Alternativley, rather than having to include every required component definition in the parent
Applications factory configruation, each Module can
define it's own factory and configuration - again the Configure tag
will use the first MxmlObjectFactory it finds.
The below sample application loads two Modules - one with its own factory and one wihtout:
<FliccListener>
<MxmlObjectFactory>
<sample:BasicModuleConfig />
</MxmlObjectFactory>
</FliccListener>
<mx:HDividedBox width="100%" height="100%">
<mx:ModuleLoader url="ModuleWithFactory.swf"
id="moduleWithFactory"
width="50%"/>
<mx:ModuleLoader url="ModuleWithoutFactory.swf"
id="moduleWithoutFactory"
width="50%" />
</mx:HDividedBox>
The Module without a factory includes a Configure tag
with the objectId of moduleComponent. This
maps to a Component definition in the parent Application
factory config:
<mx:Module>
<mx:Script>
<![CDATA[
import basicmoduleapplication.WelcomeModel;
[Bindable]
public var model : WelcomeModel;
]]>
</mx:Script>
<Configure objectId="modulecomponent" />
<mx:Label fontWeight="bold" text="Module Without Factory" />
<mx:Label text="{model.message}" />
</mx:Module>
<Component objectId="modulecomponent">
<model>
<Object clazz="{WelcomeModel}">
<message>This is from the parent application!</message>
</Object>
</model>
</Component>
When the creationComplete event of the Module
fires, the MxmlObjectFactory in the parent Application
will be used to the configure the module.
Rather than using the parent MxmlObjectFactory, the other
Module declares it's own factory and configuration. The
Configure tag is used in the same way, but now the first
FliccListener in the display hierarchy is the one on the
Module rather than the parent Application - so
this will be used to to configure components.
<mx:Module>
<mx:Script>
<![CDATA[
import basicmoduleapplication.WelcomeModel;
[Bindable]
public var model : WelcomeModel;
]]>
</mx:Script>
<FliccListener>
<MxmlObjectFactory>
<sample:ModuleConfig />
</MxmlObjectFactory>
</FliccListener>
<Configure objectId="component" />
<mx:Label fontWeight="bold" text="Module With Factory" />
<mx:Label text="{model.message}" />
</mx:Module>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component objectId="component">
<model>
<Object clazz="{WelcomeModel}">
<message>This is from the Module config!</message>
</Object>
</model>
</Component>
</descriptors>
</MxmlFactoryConfig>
3.2. Sharing Objects
You can also use the ExternalObjects tag to pass objects from a parent
Application in to the Modules factory, and then have these
objects injected on to components in the Module. In the below example,
the Customers object is first provided to the loaded module using the
ModuleLoader:
<mx:Script>
<![CDATA[
[Bindable]
public var model : Customers;
private function handleModuleReady() : void
{
var module : ICustomerModule =
ICustomerModule( viewCustomer.child );
module.customers = model;
}
]]>
</mx:Script>
<mx:ModuleLoader
id="viewCustomer"
label="View Customer"
url="viewcustomermodule.swf"
ready="handleModuleReady()"
width="100%"
height="100%" />
The Module's factory then declares an ExternalObjects
instance on it's factory configuration, binding the Customers instance
to a dynamic property named customers:
<mx:Script>
<![CDATA[
import sharingmodule.Customers;
[Bindable]
private var _customers : Customers;
public function set customers( value : Customers ) : void
{
this._customers = value;
}
]]>
</mx:Script>
<FliccListener>
<MxmlObjectFactory id="factory">
<sample:ViewCustomerModuleConfig>
<ExternalObjects customers="{ _customers }" />
</sample:ViewCustomerModuleConfig>
</MxmlObjectFactory>
</FliccListener>
<sample:ViewCustomerComponent id="viewCustomerComponent" />
The Customers instance can now be referred to within the
factoy configuration using the objectId of customers:
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component objectId="viewCustomerComponent">
<model>
<Ref to="customers" />
</model>
</Component>
</descriptors>
</MxmlFactoryConfig>
3.3. Destroying Factories
Before you unload a Module that uses Flicc, you can call destroy
on the MxmlObjectFactory of the Module - this will cause the factory
to release all references to any objects it has created and invoke the destroyMethod
on any created object that has specified one.
The example below uses the ModuleLoader to load and unload a
Module. The Module implements the IFliccModule
interface which contains one method, unloadFactory. When the
Module is unloaded by the parent application, this method is invoked:
<mx:Script>
private var module : IModuleInfo;
private var moduleInstance : IFliccModule;
private function loadModules() : void
{
module = ModuleManager.getModule("DestroyableModule.swf");
module.load();
}
private function unloadModule() : void
{
if(moduleInstance)
moduleInstance.unloadFactory();
moduleContainer.removeAllChildren();
moduleInstance = null;
}
private function loadModule() : void
{
if(moduleInstance)
unloadModule();
var newModuleInstance : DisplayObject
= DisplayObject( module.factory.create() );
moduleContainer.addChild( newModuleInstance );
moduleInstance = IFliccModule( newModuleInstance );
}
</mx:Script>
<mx:HBox width="100%">
<mx:Button label="Load Module" click="loadModule()" />
<mx:Button label="Unload Module" click="unloadModule()" />
</mx:HBox>
<mx:Canvas id="moduleContainer" width="100%" height="100%" />
The actual Module component invokes the destroy method
on its factory when unloadFactory is invoked:
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flicc="http://flicc.sourceforge.net"
xmlns:sample="destroyablemodule.*"
styleName="module"
width="100%"
height="100%"
implements="unloadingmoduleapplication.IFliccModule">
<flicc:FliccListener>
<flicc:MxmlObjectFactory id="factory">
<sample:ModuleConfig />
</flicc:MxmlObjectFactory>
</flicc:FliccListener>
<flicc:Configure id="module" />
<mx:Script>
import unloadingmoduleapplication.WelcomeModel;
[Bindable]
public var model : WelcomeModel;
public function unloadFactory() : void
{
factory.destroy();
}
</mx:Script>
<mx:Label text="Message: {model.message}" />
</mx:Module>
This causes the
factory to call the destroyMethod (if defined) on any objects
it has created. In this case, the WelcomeModel created by the
factory defined a destroy method named 'cleanUp':
<?xml version="1.0" encoding="utf-8"?>
<MxmlFactoryConfig xmlns="http://flicc.sourceforge.net"
xmlns:sample="modularapplication.*"
xmlns:mx="http://www.adobe.com/2006/mxml">
<descriptors>
<Component id="module">
<model>
<Object clazz="{ WelcomeModel }" initialiseMethod="init"
destroyMethod="cleanUp"/>
</model>
</Component>
</descriptors>
</MxmlFactoryConfig>
The WelcomeModels cleanUp method simply
displays an Alert, but the destroyMethod can be used
to remove references from Singletons and peform any other required
clean up when unloading modules.