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

Commit

Permalink
Further refactoring of injection configuration: InjectionPoints now g…
Browse files Browse the repository at this point in the history
…et assigned a fixed InjectionConfig which may or may not already have a result to return instead of querying the Injectors mappings each time an injection request for the InjectionPoint is made.

Reasoning for this change:
The InjectionConfig shouldn't be resolved anew each time a request for its result is made.
Also, this is the last big step of preparation for creating child injectors that forward requests they can't fulfill themself to a parent injector.
  • Loading branch information
tschneidereit committed Feb 9, 2010
1 parent d9faeb3 commit b9510f0
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 187 deletions.
2 changes: 1 addition & 1 deletion src/org/swiftsuspenders/InjectionConfig.as
@@ -1 +1 @@
/** 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.getResponse(); } 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 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; } }}
Expand Down
56 changes: 28 additions & 28 deletions src/org/swiftsuspenders/Injector.as
Expand Up @@ -52,15 +52,15 @@ package org.swiftsuspenders

public function mapValue(whenAskedFor : Class, useValue : Object, named : String = "") : *
{
var config : InjectionConfig = getMappingConfig(whenAskedFor, named);
var config : InjectionConfig = getMapping(whenAskedFor, named);
config.setResult(new InjectValueResult(useValue, this));
return config;
}

public function mapClass(
whenAskedFor : Class, instantiateClass : Class, named : String = "") : *
{
var config : InjectionConfig = getMappingConfig(whenAskedFor, named);
var config : InjectionConfig = getMapping(whenAskedFor, named);
config.setResult(new InjectClassResult(instantiateClass, this));
return config;
}
Expand All @@ -73,7 +73,7 @@ package org.swiftsuspenders
public function mapSingletonOf(
whenAskedFor : Class, useSingletonOf : Class, named : String = "") : *
{
var config : InjectionConfig = getMappingConfig(whenAskedFor, named);
var config : InjectionConfig = getMapping(whenAskedFor, named);
var singletons : Dictionary = m_singletons;
if (named)
{
Expand All @@ -89,11 +89,31 @@ package org.swiftsuspenders

public function mapRule(whenAskedFor : Class, useRule : *, named : String = "") : *
{
var config : InjectionConfig = getMappingConfig(whenAskedFor, named);
var config : InjectionConfig = getMapping(whenAskedFor, named);
config.setResult(new InjectOtherRuleResult(useRule));
return useRule;
}

public function getMapping(whenAskedFor : Class, named : String = null) : InjectionConfig
{
var requestName : String = getQualifiedClassName(whenAskedFor);
var mappings : Dictionary = m_mappings;
if (named)
{
mappings = mappings[named];
if (!mappings)
{
mappings = m_mappings[named] = new Dictionary();
}
}
var config : InjectionConfig = mappings[requestName];
if (!config)
{
config = mappings[requestName] = new InjectionConfig(whenAskedFor, named, this);
}
return config;
}

public function injectInto(target : Object) : void
{
if (m_attendedToInjectees[target])
Expand Down Expand Up @@ -164,26 +184,6 @@ package org.swiftsuspenders
/*******************************************************************************************
* protected/ private methods *
*******************************************************************************************/
private function getMappingConfig(request : Class, named : String) : InjectionConfig
{
var requestName : String = getQualifiedClassName(request);
var mappings : Dictionary = m_mappings;
if (named)
{
mappings = mappings[named];
if (!mappings)
{
mappings = m_mappings[named] = new Dictionary();
}
}
var config : InjectionConfig = mappings[requestName];
if (!config)
{
config = mappings[requestName] = new InjectionConfig(request, named, this);
}
return config;
}

private function getInjectionPoints(clazz : Class) : Array
{
var description : XML = describeType(clazz);
Expand All @@ -205,7 +205,7 @@ package org.swiftsuspenders
if (node)
{
m_constructorInjectionPoints[clazz] =
new ConstructorInjectionPoint(node, m_mappings, clazz);
new ConstructorInjectionPoint(node, clazz, this);
}
else
{
Expand All @@ -215,22 +215,22 @@ package org.swiftsuspenders
for each (node in description.factory.*.
(name() == 'variable' || name() == 'accessor').metadata.(@name == 'Inject'))
{
injectionPoint = new PropertyInjectionPoint(node, m_mappings);
injectionPoint = new PropertyInjectionPoint(node, this);
injectionPoints.push(injectionPoint);
}

//get injection points for methods
for each (node in description.factory.method.metadata.(@name == 'Inject'))
{
injectionPoint = new MethodInjectionPoint(node, m_mappings);
injectionPoint = new MethodInjectionPoint(node, this);
injectionPoints.push(injectionPoint);
}

//get post construct methods
var postConstructMethodPoints : Array = [];
for each (node in description.factory.method.metadata.(@name == 'PostConstruct'))
{
injectionPoint = new PostConstructInjectionPoint(node, m_mappings);
injectionPoint = new PostConstructInjectionPoint(node, this);
postConstructMethodPoints.push(injectionPoint);
}
if (postConstructMethodPoints.length > 0)
Expand Down
Expand Up @@ -7,19 +7,16 @@

package org.swiftsuspenders.injectionpoints
{
import flash.utils.Dictionary;
import flash.utils.describeType;

import org.swiftsuspenders.InjectionConfig;
import org.swiftsuspenders.Injector;
import org.swiftsuspenders.InjectorError;

public class ConstructorInjectionPoint extends MethodInjectionPoint
{
/*******************************************************************************************
* public methods *
*******************************************************************************************/
public function ConstructorInjectionPoint(node : XML, injectorMappings : Dictionary, clazz : Class)
public function ConstructorInjectionPoint(node : XML, clazz : Class, injector : Injector)
{
/*
In many cases, the flash player doesn't give us type information for constructors until
Expand All @@ -30,7 +27,7 @@ package org.swiftsuspenders.injectionpoints
{
createDummyInstance(node, clazz);
}
super(node, injectorMappings);
super(node, injector);
}

override public function applyInjection(target : Object) : Object
Expand All @@ -57,13 +54,12 @@ package org.swiftsuspenders.injectionpoints
/*******************************************************************************************
* protected methods *
*******************************************************************************************/
override protected function initializeInjection(node : XML, injectorMappings : Dictionary) : void
override protected function initializeInjection(node : XML, injector : Injector) : void
{
var nameArgs : XMLList = node.parent().metadata.(@name == 'Inject').arg.(@key == 'name');
mappings = [];
parameterTypes = [];
methodName = 'constructor';

gatherParameters(node, nameArgs, injectorMappings);
gatherParameters(node, nameArgs, injector);
}

/*******************************************************************************************
Expand Down
14 changes: 4 additions & 10 deletions src/org/swiftsuspenders/injectionpoints/InjectionPoint.as
Expand Up @@ -7,22 +7,16 @@

package org.swiftsuspenders.injectionpoints
{
import flash.utils.Dictionary;
import org.swiftsuspenders.Injector;

public class InjectionPoint
{
/*******************************************************************************************
* protected properties *
*******************************************************************************************/
protected var injectionName : String;


/*******************************************************************************************
* public methods *
*******************************************************************************************/
public function InjectionPoint(node : XML, injectorMappings : Dictionary)
public function InjectionPoint(node : XML, injector : Injector)
{
initializeInjection(node, injectorMappings);
initializeInjection(node, injector);
}

public function applyInjection(target : Object) : Object
Expand All @@ -34,7 +28,7 @@ package org.swiftsuspenders.injectionpoints
/*******************************************************************************************
* protected methods *
*******************************************************************************************/
protected function initializeInjection(node : XML, injectorMappings : Dictionary) : void
protected function initializeInjection(node : XML, injector : Injector) : void
{
}
}
Expand Down
54 changes: 29 additions & 25 deletions src/org/swiftsuspenders/injectionpoints/MethodInjectionPoint.as
Expand Up @@ -7,9 +7,11 @@

package org.swiftsuspenders.injectionpoints
{
import flash.utils.Dictionary;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;

import org.swiftsuspenders.InjectionConfig;
import org.swiftsuspenders.Injector;
import org.swiftsuspenders.InjectorError;

public class MethodInjectionPoint extends InjectionPoint
Expand All @@ -18,17 +20,16 @@ package org.swiftsuspenders.injectionpoints
* private properties *
*******************************************************************************************/
protected var methodName : String;
protected var mappings : Array;
protected var parameterTypes : Array;
protected var m_injectionConfigs : Array;
protected var requiredParameters : int = 0;


/*******************************************************************************************
* public methods *
*******************************************************************************************/
public function MethodInjectionPoint(node : XML, injectorMappings : Dictionary)
public function MethodInjectionPoint(node : XML, injector : Injector)
{
super(node, injectorMappings);
super(node, injector);
}

override public function applyInjection(target : Object) : Object
Expand All @@ -43,44 +44,47 @@ package org.swiftsuspenders.injectionpoints
/*******************************************************************************************
* protected methods *
*******************************************************************************************/
override protected function initializeInjection(node : XML, injectorMappings : Dictionary) : void
override protected function initializeInjection(node : XML, injector : Injector) : void
{
var nameArgs : XMLList = node.arg.(@key == 'name');
var methodNode : XML = node.parent();

methodName = methodNode.@name.toString();
mappings = [];
parameterTypes = [];

gatherParameters(methodNode, nameArgs, injectorMappings);
gatherParameters(methodNode, nameArgs, injector);
}

protected function gatherParameters(
methodNode : XML, nameArgs : XMLList, injectorMappings : Dictionary) : void
methodNode : XML, nameArgs : XMLList, injector : Injector) : void
{
m_injectionConfigs = [];
var i : int = 0;
for each (var parameter : XML in methodNode.parameter)
{
var parameterMappings : Dictionary;
var injectionName : String;
if (nameArgs[i])
{
injectionName = nameArgs[i].@value.toString();
}
if (injectionName)
var parameterTypeName : String = parameter.@type.toString();
var parameterType : Class;
if (parameterTypeName == '*')
{
parameterMappings = injectorMappings[injectionName];
if (!parameterMappings)
if (parameter.@optional.toString() == 'false')
{
//TODO: Find a way to trace name of affected class here
throw new Error('Error in method definition of injectee. Required ' +
'parameters can\'t have type "*".');
}
else
{
parameterMappings = injectorMappings[injectionName] = new Dictionary();
parameterTypeName = null;
}
}
else
{
parameterMappings = injectorMappings;
parameterType = Class(getDefinitionByName(parameterTypeName));
}
mappings.push(parameterMappings);
parameterTypes.push(parameter.@type.toString());
m_injectionConfigs.push(injector.getMapping(parameterType, injectionName));
if (parameter.@optional.toString() == 'false')
{
requiredParameters++;
Expand All @@ -92,24 +96,24 @@ package org.swiftsuspenders.injectionpoints
protected function gatherParameterValues(target : Object) : Array
{
var parameters : Array = [];
var length : int = mappings.length;
var length : int = m_injectionConfigs.length;
for (var i : int = 0; i < length; i++)
{
var config : InjectionConfig = mappings[i][parameterTypes[i]];
if (!config)
var config : InjectionConfig = m_injectionConfigs[i];
var injection : Object = config.getResponse();
if (!injection)
{
if (i >= requiredParameters)
{
break;
}
throw(new InjectorError(
'Injector is missing a rule to handle injection into target ' + target +
'. Target dependency: ' + parameterTypes[i] + ', method: ' + methodName +
', parameter: ' + (i + 1)
'. Target dependency: ' + getQualifiedClassName(config.request) +
', method: ' + methodName + ', parameter: ' + (i + 1)
));
}

var injection : Object = config.getResponse();
parameters[i] = injection;
}
return parameters;
Expand Down
Expand Up @@ -7,7 +7,7 @@

package org.swiftsuspenders.injectionpoints
{
import flash.utils.Dictionary;
import org.swiftsuspenders.Injector;

public class PostConstructInjectionPoint extends InjectionPoint
{
Expand All @@ -21,9 +21,9 @@ package org.swiftsuspenders.injectionpoints
/*******************************************************************************************
* public methods *
*******************************************************************************************/
public function PostConstructInjectionPoint(node:XML, injectorMappings:Dictionary)
public function PostConstructInjectionPoint(node:XML, injector : Injector)
{
super(node, injectorMappings);
super(node, injector);
}

public function get order():int
Expand All @@ -41,7 +41,7 @@ package org.swiftsuspenders.injectionpoints
/*******************************************************************************************
* protected methods *
*******************************************************************************************/
override protected function initializeInjection(node : XML, injectorMappings : Dictionary) : void
override protected function initializeInjection(node : XML, injector : Injector) : void
{
var orderArg : XMLList = node.arg.(@key == 'order');
var methodNode : XML = node.parent();
Expand Down

0 comments on commit b9510f0

Please sign in to comment.