Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Basic metadata-based IOC solution for AS3
ActionScript Shell

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
build
src/org/swiftsuspenders
test
.gitattributes
.gitignore
README.textile
build.properties
build.xml

README.textile

SwiftSuspenders

SwiftSuspenders is a very basic metadata driven IOC (Inversion Of Control) solution for AS3. In its basic approach, it is similar to the SmartyPants IOC framework, but it differs from SmartyPants in two respects: It is inferior in capabilities and it is quite somewhat faster.

Its main Raison d’être is supporting the very nice RobotLegs AS3 MCVS framework by Shaun Smith – hence the name.

Installation

The easiest way to use SwiftSuspenders is by adding the provided swc file to your project. If you want to use the source, you have to add the following parameter to your MXMLC settings:

-keep-as3-metadata+=Inject

Usage

Defining dependencies

SwiftSuspenders supports three types of dependency definitions:

  • value bindings, which simply map an injection request to be satisfied by injecting the given object
  • class bindings, which map an injection request to be satisfied by injecting a new instance of the given class
  • singleton bindings, which map all injection requests for the given class by injecting the same shared instance, which itself gets created on first request

For all three definition types, it’s possible to specify names, which allows using multiple injection bindings to the same class.

Defining injection points

Dependency bindings can be injected into an object using constructor injection, setter injection, field injection or method injection (or a combination of these).
setter, field and method injection require metadata for all injections to be added to the injectee class, whereas you only need to add metadata for named dependencies when using constructor injection:

[Inject]

and for injecting named dependencies

[Inject(name="NamedDependency")]

When using named dependencies for constructor injection, the metadata has to be placed above the class definition, not above the constructor. This is an unfortunate restriction the Flash Player imposes.

For methods and constructors accepting multiple parameters, it’s possible to define mixes of named and unnamed dependency bindings. In this case, trailing unnamed dependencies can simply be omitted in the metadata, whereas unnamed dependencies followed by named ones have to be declared as the empty string:

[Inject(name='', name="NamedDependency")]

Examples

Field and Setter Injection

Suppose you have a class into which you want to inject dependencies that looks like this (Note that I’ve left out import statements for brevity):

package
{
	public class MyDependentClass
	{
		[Inject]
		public var firstDepency : MovieClip;
		
		[Inject(name="currentTime")]
		public var secondDependency : Date;
		
		[Inject]
		public function set thirdDependency(value : Sprite) : void
		{
			m_thirdDependency = value;
		}
		private var m_thirdDependency : Sprite;
	}
}

To inject dependencies into an instance of this class, you would first define dependency mappings and then invoke SwiftSuspendersInjector#injectInto:

var injector : SwiftSuspendersInjector = new SwiftSuspendersInjector();
injector.mapValue(MovieClip, new MovieClip());
var currentTime : Date = new Date();
injector.mapClass(Date, currentTime, 'currentTime');
injector.mapSingleton(Sprite); //obviously, you wouldn't _really_ use Sprite singletons
var injectee : MyDependentClass = new MyDependentClass();
injector.injectInto(injectee);

Method Injection

Suppose you have a class into which you want to inject dependencies that looks like this (Note that I’ve left out import statements for brevity):

package
{
	public class MyDependentClass
	{
		private var myMovieClip : MovieClip;
		private var currentTime : Date;
		
		[Inject]
		public function setFirstDependency(injection : MovieClip) : void
		{
			myMovieClip = injection;
		}
		
		[Inject(name="currentTime")]
		public function setSecondDependency(injection : Date) : void
		{
			currentTime = injection;
		}
		
		[Inject(name='', name="currentTime")]
		public function setMultipleDependencies(movieClip : MovieClip, date : Date) : void
		{
			myMovieClip = movieClip;
			currentTime = date;
		}
	}
}

To inject dependencies into an instance of this class, you would first define dependency mappings and then invoke SwiftSuspendersInjector#injectInto:

var injector : SwiftSuspendersInjector = new SwiftSuspendersInjector();
injector.mapValue(MovieClip, new MovieClip());
var currentTime : Date = new Date();
injector.mapValue(Date, currentTime, 'currentTime');
var injectee : TestInjectee = new TestInjectee();
injector.injectInto(injectee);

In this case, the defined dependencies are partly redundant, which is waste- but otherwise not harmful.

Constructor Injection

Suppose you have a class into which you want to inject dependencies that looks like this (Note that I’ve left out import statements for brevity):

package
{
	[Inject(name='', name="currentTime")]
	public class MyDependentClass
	{
		private var myMovieClip : MovieClip;
		private var currentTime : Date;
		
		public function MyDependentClass(movieClip : MovieClip, date : Date)
		{
			myMovieClip = movieClip;
			currentTime = date;
		}
	}
}

To inject dependencies into an instance of this class, you would first define dependency mappings and then invoke SwiftSuspendersInjector#instantiate:

var injector : SwiftSuspendersInjector = new SwiftSuspendersInjector();
injector.mapValue(MovieClip, new MovieClip());
var currentTime : Date = new Date();
injector.mapValue(Date, currentTime, 'currentTime');
var injectee : TestInjectee = injector.instantiate(TestInjectee);

More Information

As these are a rather contrived and useless examples, I urge you to check out RobotLegs and its examples, which contain much better examples for using IOC in AS3.

Something went wrong with that request. Please try again.