Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
Added support for child injectors, enabling usage of different inject…
Browse files Browse the repository at this point in the history
…ion mappings for parts of a dependency tree

In addition, injection results classes have been refactored to inherit from a base class instead of implementing an interface to facilitate code-reuse
  • Loading branch information
tschneidereit committed Feb 9, 2010
1 parent b9510f0 commit c63091d
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 17 deletions.
3 changes: 2 additions & 1 deletion src/org/swiftsuspenders/InjectionConfig.as
@@ -1 +1,2 @@
/** Copyright (c) 2009 the original author or authors* * Permission is hereby granted to use, modify, and distribute this file * in accordance with the terms of the license agreement accompanying it.*/package org.swiftsuspenders{ import flash.utils.Dictionary; import org.swiftsuspenders.injectionresults.IInjectionResult; public class InjectionConfig { /******************************************************************************************* * public properties * *******************************************************************************************/ public var request : Class; public var injectionName : String; /******************************************************************************************* * private properties * *******************************************************************************************/ private var m_injector : Injector; private var m_result : IInjectionResult; /******************************************************************************************* * public methods * *******************************************************************************************/ public function InjectionConfig( request : Class, injectionName : String, injector : Injector) { this.request = request; this.injectionName = injectionName; m_injector = injector; } public function getResponse() : Object { return m_result ? m_result.getResponse() : null; } public function setResult(result : IInjectionResult) : void { m_result = result; } }}
/** Copyright (c) 2009 the original author or authors* * Permission is hereby granted to use, modify, and distribute this file * in accordance with the terms of the license agreement accompanying it.*/package org.swiftsuspenders{ import org.swiftsuspenders.injectionresults.InjectionResult;
public class InjectionConfig { /******************************************************************************************* * public properties * *******************************************************************************************/ public var request : Class; public var injectionName : String; /******************************************************************************************* * private properties * *******************************************************************************************/ private var m_injector : Injector; private var m_result : InjectionResult; /******************************************************************************************* * public methods * *******************************************************************************************/ public function InjectionConfig( request : Class, injectionName : String, injector : Injector) { this.request = request; this.injectionName = injectionName; m_injector = injector; } public function getResponse() : Object { if (m_result) { return m_result.getResponse(); } var parentConfig : InjectionConfig = m_injector.getParentMapping(request, injectionName); if (parentConfig) { return parentConfig.getResponse(); } return null; } public function setResult(result : InjectionResult) : void { m_result = result; } public function setInjector(injector : Injector) : void { m_injector = injector; m_result.setInjector(injector); } }}
Expand Down
22 changes: 20 additions & 2 deletions src/org/swiftsuspenders/Injector.as
Expand Up @@ -29,6 +29,7 @@ package org.swiftsuspenders
/*******************************************************************************************
* private properties *
*******************************************************************************************/
private var m_parentInjector : Injector;
private var m_mappings : Dictionary;
private var m_singletons : Dictionary;
private var m_injectionPointLists : Dictionary;
Expand Down Expand Up @@ -177,12 +178,24 @@ package org.swiftsuspenders

public function createChildInjector() : Injector
{
return new Injector();
var injector : Injector = new Injector();
injector.setParentInjector(this);
return injector;
}


/*******************************************************************************************
* protected/ private methods *
* internal methods *
*******************************************************************************************/
internal function getParentMapping(
whenAskedFor : Class, named : String = null) : InjectionConfig
{
return m_parentInjector ? m_parentInjector.getMapping(whenAskedFor, named) : null;
}


/*******************************************************************************************
* private methods *
*******************************************************************************************/
private function getInjectionPoints(clazz : Class) : Array
{
Expand Down Expand Up @@ -301,5 +314,10 @@ package org.swiftsuspenders
getInjectionPoints(Class(getDefinitionByName(parentClassName)));
injectionPoints.push.apply(injectionPoints, parentInjectionPoints);
}

private function setParentInjector(parentInjector : Injector) : void
{
m_parentInjector = parentInjector;
}
}
}
7 changes: 3 additions & 4 deletions src/org/swiftsuspenders/injectionresults/InjectClassResult.as
Expand Up @@ -9,13 +9,12 @@ package org.swiftsuspenders.injectionresults
{
import org.swiftsuspenders.Injector;

public class InjectClassResult implements IInjectionResult
public class InjectClassResult extends InjectionResult
{
/*******************************************************************************************
* private properties *
*******************************************************************************************/
private var m_responseType : Class;
private var m_injector : Injector;


/*******************************************************************************************
Expand All @@ -24,10 +23,10 @@ package org.swiftsuspenders.injectionresults
public function InjectClassResult(responseType : Class, injector : Injector)
{
m_responseType = responseType;
m_injector = injector;
super(injector);
}

public function getResponse() : Object
override public function getResponse() : Object
{
return m_injector.instantiate(m_responseType);
}
Expand Down
Expand Up @@ -9,7 +9,7 @@ package org.swiftsuspenders.injectionresults
{
import org.swiftsuspenders.InjectionConfig;

public class InjectOtherRuleResult implements IInjectionResult
public class InjectOtherRuleResult extends InjectionResult
{
/*******************************************************************************************
* private properties *
Expand All @@ -23,9 +23,10 @@ package org.swiftsuspenders.injectionresults
public function InjectOtherRuleResult(rule : InjectionConfig)
{
m_rule = rule;
super(null);
}

public function getResponse() : Object
override public function getResponse() : Object
{
return m_rule.getResponse();
}
Expand Down
Expand Up @@ -11,15 +11,14 @@ package org.swiftsuspenders.injectionresults

import org.swiftsuspenders.Injector;

public class InjectSingletonResult implements IInjectionResult
public class InjectSingletonResult extends InjectionResult
{
/*******************************************************************************************
* private properties *
*******************************************************************************************/
private var m_singletons : Dictionary;
private var m_responseType : Class;
private var m_response : Object;
private var m_injector : Injector;


/*******************************************************************************************
Expand All @@ -30,10 +29,10 @@ package org.swiftsuspenders.injectionresults
{
m_singletons = singletons;
m_responseType = responseType;
m_injector = injector;
super(injector);
}

public function getResponse() : Object
override public function getResponse() : Object
{
return m_response || createResponse();
}
Expand Down
7 changes: 3 additions & 4 deletions src/org/swiftsuspenders/injectionresults/InjectValueResult.as
Expand Up @@ -9,13 +9,12 @@ package org.swiftsuspenders.injectionresults
{
import org.swiftsuspenders.Injector;

public class InjectValueResult implements IInjectionResult
public class InjectValueResult extends InjectionResult
{
/*******************************************************************************************
* private properties *
*******************************************************************************************/
private var m_value : Object
private var m_injector : Injector;


/*******************************************************************************************
Expand All @@ -24,10 +23,10 @@ package org.swiftsuspenders.injectionresults
public function InjectValueResult(value : Object, injector : Injector)
{
m_value = value;
m_injector = injector;
super(injector);
}

public function getResponse() : Object
override public function getResponse() : Object
{
m_injector.injectInto(m_value);
return m_value;
Expand Down
38 changes: 38 additions & 0 deletions src/org/swiftsuspenders/injectionresults/InjectionResult.as
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.injectionresults
{
import org.swiftsuspenders.Injector;

public class InjectionResult
{
/*******************************************************************************************
* protected properties *
*******************************************************************************************/
protected var m_injector : Injector;


/*******************************************************************************************
* public methods *
*******************************************************************************************/
public function InjectionResult(injector : Injector)
{
m_injector = injector;
}

public function getResponse() : Object
{
return null;
}

public function setInjector(injector : Injector) : void
{
m_injector = injector;
}
}
}
85 changes: 85 additions & 0 deletions test/org/swiftsuspenders/ChildInjectorTests.as
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders
{
import flexunit.framework.Assert;

import org.swiftsuspenders.support.injectees.childinjectors.LeftRobotFoot;
import org.swiftsuspenders.support.injectees.childinjectors.RightRobotFoot;
import org.swiftsuspenders.support.injectees.childinjectors.RobotBody;
import org.swiftsuspenders.support.injectees.childinjectors.RobotFoot;
import org.swiftsuspenders.support.injectees.childinjectors.RobotLeg;
import org.swiftsuspenders.support.injectees.childinjectors.RobotToes;

public class ChildInjectorTests
{
protected var injector:Injector;

[Before]
public function runBeforeEachTest():void
{
injector = new Injector();
}

[Test]
public function injectorCreatesChildInjector() : void
{
Assert.assertTrue(true);
var childInjector : Injector = injector.createChildInjector();
Assert.assertTrue('injector.createChildInjector should return an injector',
childInjector is Injector);
}

[Test]
public function injectorUsesChildInjectorForSpecifiedRule() : void
{
injector.mapClass(RobotFoot, RobotFoot);

var leftFootRule : InjectionConfig = injector.mapClass(RobotLeg, RobotLeg, 'leftLeg');
var leftChildInjector : Injector = injector.createChildInjector();
leftChildInjector.mapClass(RobotFoot, LeftRobotFoot);
leftFootRule.setInjector(leftChildInjector);

var rightFootRule : InjectionConfig = injector.mapClass(RobotLeg, RobotLeg, 'rightLeg');
var rightChildInjector : Injector = injector.createChildInjector();
rightChildInjector.mapClass(RobotFoot, RightRobotFoot);
rightFootRule.setInjector(rightChildInjector);

var robotBody : RobotBody = injector.instantiate(RobotBody);

Assert.assertTrue('Right RobotLeg should have a RightRobotFoot',
robotBody.rightLeg.foot is RightRobotFoot);
Assert.assertTrue('Left RobotLeg should have a LeftRobotFoot',
robotBody.leftLeg.foot is LeftRobotFoot);
}

[Test]
public function childInjectorUsesParentInjectorForMissingRules() : void
{
injector.mapClass(RobotFoot, RobotFoot);
injector.mapClass(RobotToes, RobotToes);

var leftFootRule : InjectionConfig = injector.mapClass(RobotLeg, RobotLeg, 'leftLeg');
var leftChildInjector : Injector = injector.createChildInjector();
leftChildInjector.mapClass(RobotFoot, LeftRobotFoot);
leftFootRule.setInjector(leftChildInjector);

var rightFootRule : InjectionConfig = injector.mapClass(RobotLeg, RobotLeg, 'rightLeg');
var rightChildInjector : Injector = injector.createChildInjector();
rightChildInjector.mapClass(RobotFoot, RightRobotFoot);
rightFootRule.setInjector(rightChildInjector);

var robotBody : RobotBody = injector.instantiate(RobotBody);

Assert.assertTrue('Right RobotFoot should have toes',
robotBody.rightLeg.foot.toes is RobotToes);
Assert.assertTrue('Left Robotfoot should have a toes',
robotBody.leftLeg.foot.toes is RobotToes);
}
}
}
2 changes: 2 additions & 0 deletions test/org/swiftsuspenders/suites/SwiftSuspendersTestSuite.as
Expand Up @@ -22,6 +22,7 @@

package org.swiftsuspenders.suites
{
import org.swiftsuspenders.ChildInjectorTests;
import org.swiftsuspenders.InjectionConfigTests;
import org.swiftsuspenders.InjectorTests;
import org.swiftsuspenders.ReflectorTests;
Expand All @@ -43,5 +44,6 @@ package org.swiftsuspenders.suites
public var noParamConstructorInjectionPoint:NoParamsConstructorInjectionPointTests;
public var constructorInjectionPointTests:ConstructorInjectionPointTests;
public var injectionConfigTests:InjectionConfigTests;
public var childInjectorTests : ChildInjectorTests;
}
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.support.injectees.childinjectors
{
public class LeftRobotFoot extends RobotFoot
{
public function LeftRobotFoot(toes : RobotToes = null)
{
super(toes);
}
}
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.support.injectees.childinjectors
{
public class RightRobotFoot extends RobotFoot
{
public function RightRobotFoot(toes : RobotToes = null)
{
super(toes);
}
}
}
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.support.injectees.childinjectors
{
public class RobotBody
{
[Inject(name='leftLeg')]
public var leftLeg : RobotLeg;

[Inject(name='rightLeg')]
public var rightLeg : RobotLeg;
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.support.injectees.childinjectors
{
public class RobotFoot
{
public var toes : RobotToes;

public function RobotFoot(toes : RobotToes = null)
{
this.toes = toes;
}
}
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2009 the original author or authors
*
* Permission is hereby granted to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
*/

package org.swiftsuspenders.support.injectees.childinjectors
{
public class RobotLeg
{
[Inject]
public var foot : RobotFoot;
}
}

0 comments on commit c63091d

Please sign in to comment.