Skip to content

Commit

Permalink
Merge pull request #55 from seancorfield/master
Browse files Browse the repository at this point in the history
Fixes #52 by adding overrides.
  • Loading branch information
seancorfield committed Nov 3, 2013
2 parents 314e294 + ab9bdda commit e9b5897
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 18 deletions.
44 changes: 30 additions & 14 deletions ioc.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ component {


// programmatically register new beans with the factory (add an actual CFC)
public any function declareBean( string beanName, string dottedPath, boolean isSingleton = true ) {
public any function declareBean( string beanName, string dottedPath, boolean isSingleton = true, struct overrides = { } ) {
discoverBeans( variables.folders );
var singleDir = '';
if ( listLen( dottedPath, '.' ) > 1 ) {
Expand All @@ -68,7 +68,8 @@ component {
var cfcPath = replace( expandPath( '/' & replace( dottedPath, '.', '/', 'all' ) & '.cfc' ), chr(92), '/', 'all' );
var metadata = {
name = beanName, qualifier = singleDir, isSingleton = isSingleton,
path = cfcPath, cfc = dottedPath, metadata = cleanMetadata( dottedPath )
path = cfcPath, cfc = dottedPath, metadata = cleanMetadata( dottedPath ),
overrides = overrides
};
variables.beanInfo[ beanName ] = metadata;
return this;
Expand Down Expand Up @@ -485,7 +486,9 @@ component {
var injection = partialBean.injection[ name ];
for ( var property in injection.setters ) {
var args = { };
if ( structKeyExists( partialBean.injection, property ) ) {
if ( structKeyExists( injection.overrides, property ) ) {
args[ property ] = injection.overrides[ property ];
} else if ( structKeyExists( partialBean.injection, property ) ) {
args[ property ] = partialBean.injection[ property ].bean;
} else if ( structKeyExists( variables, 'parent' ) && variables.parent.containsBean( property ) ) {
args[ property ] = variables.parent.getBean( property );
Expand All @@ -506,6 +509,7 @@ component {
var info = variables.beanInfo[ beanName ];
if ( structKeyExists( info, 'cfc' ) ) {
var metaBean = cachable( beanName );
var overrides = structKeyExists( info, 'overrides' ) ? info.overrides : { };
bean = metaBean.bean;
if ( metaBean.newObject ) {
if ( structKeyExists( info.metadata, 'constructor' ) ) {
Expand All @@ -515,7 +519,10 @@ component {
// handle known required arguments
if ( info.metadata.constructor[ arg ] ) {
var beanMissing = true;
if ( containsBean( arg ) ) {
if ( structKeyExists( overrides, arg ) ) {
args[ arg ] = overrides[ arg ];
beanMissing = false;
} else if ( containsBean( arg ) ) {
argBean = resolveBeanCreate( arg, accumulator );
if ( structKeyExists( argBean, 'bean' ) ) {
args[ arg ] = argBean.bean;
Expand All @@ -525,14 +532,18 @@ component {
if ( beanMissing ) {
throw 'bean not found: #arg#; while resolving constructor arguments for #beanName#';
}
} else if ( containsBean( arg ) ) {
// optional but present
argBean = resolveBeanCreate( arg, accumulator );
if ( structKeyExists( argBean, 'bean' ) ) {
args[ arg ] = argBean.bean;
}
} else {
// optional but not present
if ( structKeyExists( overrides, arg ) ) {
args[ arg ] = overrides[ arg ];
} else if ( containsBean( arg ) ) {
// optional but present
argBean = resolveBeanCreate( arg, accumulator );
if ( structKeyExists( argBean, 'bean' ) ) {
args[ arg ] = argBean.bean;
}
} else {
// optional but not present
}
}
}
var __ioc_newBean = evaluate( 'bean.init( argumentCollection = args )' );
Expand All @@ -552,11 +563,16 @@ component {
}
var setterMeta = {
setters = variables.settersInfo[ beanName ].setters,
bean = bean
bean = bean,
overrides = overrides
};
accumulator.injection[ beanName ] = setterMeta;
for ( var property in setterMeta.setters ) {
resolveBeanCreate( property, accumulator );
if ( structKeyExists( overrides, property ) ) {
// skip resolution because we'll inject override
} else {
resolveBeanCreate( property, accumulator );
}
}
}
accumulator.bean = bean;
Expand Down Expand Up @@ -608,7 +624,7 @@ component {
throw 'singletonPattern and transientPattern are mutually exclusive';
}

variables.config.version = '0.4.10';
variables.config.version = '0.5.0';
}


Expand Down
39 changes: 37 additions & 2 deletions tests/DeclareBean.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ component extends="mxunit.framework.TestCase" {

function shouldDeclareSingleton() {
var bf = new ioc( "" ).declareBean( "foo", "tests.extrabeans.sheep.item" );
application.itemCount = 0;
structDelete( application, "itemCount" );
var item1 = bf.getBean( "foo" );
assertEquals( 1, application.itemCount );
var item2 = bf.getBean( "foo" );
Expand All @@ -12,12 +12,47 @@ component extends="mxunit.framework.TestCase" {

function shouldDeclareTransient() {
var bf = new ioc( "" ).declareBean( "foo", "tests.extrabeans.sheep.item", false );
application.itemCount = 0;
structDelete( application, "itemCount" );
var item1 = bf.getBean( "foo" );
assertEquals( 1, application.itemCount );
var item2 = bf.getBean( "foo" );
assertEquals( 2, application.itemCount );
assertNotSame( item1, item2 );
}

function shouldDeclareSingletonWithOverride() {
var bf = new ioc( "" ).declareBean( "foo", "tests.extrabeans.sheep.item", true, { start = 100 } );
structDelete( application, "itemCount" );
var item1 = bf.getBean( "foo" );
assertEquals( 101, application.itemCount );
var item2 = bf.getBean( "foo" );
assertEquals( 101, application.itemCount );
assertSame( item1, item2 );
}

function shouldDeclareTransientWithOverride() {
var bf = new ioc( "" ).declareBean( "foo", "tests.extrabeans.sheep.item", false, { start = 100 } );
structDelete( application, "itemCount" );
var item1 = bf.getBean( "foo" );
assertEquals( 101, application.itemCount );
var item2 = bf.getBean( "foo" );
assertEquals( 102, application.itemCount );
assertNotSame( item1, item2 );
}

function shouldDeclareAndAdd() {
var bf = new ioc( "" ).declareBean( "foo", "tests.declared.things.myconfig" ).addBean( "name", "test" ).addBean( "config", "some" );
var item = bf.getBean( "foo" );
assertEquals( "test", item.getName() );
assertEquals( "some", item.getConfig() );
}

function shouldDeclareWithOverride() {
var bf = new ioc( "" ).declareBean( "foo", "tests.declared.things.myconfig", true, { name = "test", config = "some" } )
.addBean( "name", "not-test" ).addBean( "config", "config" );
var item = bf.getBean( "foo" );
assertEquals( "test", item.getName() );
assertEquals( "some", item.getConfig() );
}

}
4 changes: 2 additions & 2 deletions tests/extrabeans/sheep/item.cfc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
component accessors="true" {
property beanfactory;

function init() {
param name="application.itemCount" default="0";
function init( numeric start = 0 ) {
param name="application.itemCount" default="#start#";
this.itemNumber = ++application.itemCount;
}

Expand Down

0 comments on commit e9b5897

Please sign in to comment.