Skip to content

Commit

Permalink
Merge pull request #51 from DoclerLabs/develop
Browse files Browse the repository at this point in the history
prepare 0.19.0
  • Loading branch information
aliokan authored Apr 24, 2017
2 parents e066065 + 512332e commit ef84ae0
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 45 deletions.
15 changes: 8 additions & 7 deletions src/hex/di/Injector.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import hex.di.reflect.InjectionUtil;
import hex.error.NullPointerException;
import hex.event.ITrigger;
import hex.event.ITriggerOwner;
import hex.log.LogManager;
import hex.util.ClassUtil;

/**
Expand Down Expand Up @@ -90,7 +91,7 @@ class Injector

if ( mapping != null )
{
return mapping.getResult();
return mapping.getResult( null );
}
else if ( this._parentInjector != null )
{
Expand All @@ -110,7 +111,7 @@ class Injector

if ( mapping != null )
{
return mapping.getResult();
return mapping.getResult( Type.getClass( className.split( '<' )[ 0 ] ) );
}
else if ( this._parentInjector != null )
{
Expand Down Expand Up @@ -154,7 +155,7 @@ class Injector
var instance : T;
if ( classDescription != null && classDescription.c != null )
{
instance = InjectionUtil.applyConstructorInjection( type, this, classDescription.c.a );
instance = InjectionUtil.applyConstructorInjection( type, this, classDescription.c.a, type );
this._applyInjection( instance, type, classDescription );
}
else
Expand Down Expand Up @@ -255,7 +256,7 @@ class Injector

public function destroyInstance( instance : Dynamic ) : Void
{
if( !Reflect.isFunction(instance) )
if( !Reflect.isFunction( instance ) )
{
this._managedObjects.remove( instance );

Expand All @@ -264,7 +265,7 @@ class Injector
{
for ( preDestroy in classDescription.pd )
{
InjectionUtil.applyMethodInjection( instance, this, preDestroy.a, preDestroy.m );
InjectionUtil.applyMethodInjection( instance, this, Type.getClass( instance ), preDestroy.a, preDestroy.m );
}
}
}
Expand Down Expand Up @@ -343,7 +344,7 @@ class Injector
#if debug
if ( mapping == null )
{
trace( "Warning: unmap failed with mapping named '" + mappingID +
LogManager.getLoggerByInstance(this).warn( "Unmap failed with mapping named '" + mappingID +
"'. Maybe this mapping was overridden previously." );
}
#end
Expand Down Expand Up @@ -377,7 +378,7 @@ class Injector
this.trigger.onPreConstruct( this, target, targetType );
#end

InjectionUtil.applyClassInjection( target, this, classDescription );
InjectionUtil.applyClassInjection( target, this, classDescription, targetType );
if ( classDescription.pd.length > 0 && !Reflect.isFunction(target) )
{
this._managedObjects.put( target, target );
Expand Down
21 changes: 11 additions & 10 deletions src/hex/di/mapping/InjectionMapping.hx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import hex.di.provider.IDependencyProvider;
import hex.di.provider.SingletonProvider;
import hex.di.provider.ValueProvider;
import hex.error.NullPointerException;
import hex.log.HexLog.getLogger;

/**
* ...
Expand All @@ -24,41 +25,41 @@ class InjectionMapping<T>
this._mappingID = mappingID;
}

public function getResult() : Dynamic
public function getResult( target : Class<Dynamic> ) : Dynamic
{
if ( this.provider == null )
{
throw new NullPointerException( "can't retrieve result, mapping with id '"
+ this._mappingID + "' has no provider" );
}

return this.provider.getResult( this._injector );
return this.provider.getResult( this._injector, target );
}

inline public function toSingleton( type : Class<T> ) : InjectionMapping<T>
{
return this._toProvider( new SingletonProvider( type, this._injector ) );
return this.toProvider( new SingletonProvider( type, this._injector ) );
}

inline public function toType( type : Class<T> ) : InjectionMapping<T>
{
return this._toProvider( new ClassProvider( type ) );
return this.toProvider( new ClassProvider( type ) );
}

inline public function toValue( value : T ) : InjectionMapping<T>
{
return this._toProvider( new ValueProvider( value, this._injector ) );
return this.toProvider( new ValueProvider( value, this._injector ) );
}

inline function _toProvider( provider : IDependencyProvider<T> ) : InjectionMapping<T>
inline public function toProvider( provider : IDependencyProvider<T> ) : InjectionMapping<T>
{
#if debug
if ( this.provider != null )
{
trace( 'Warning: Injector already has a mapping for ' + this._mappingID + '.\n ' +
'If you have overridden this mapping intentionally you can use ' +
'"injector.unmap()" prior to your replacement mapping in order to ' +
'avoid seeing this message.' );
getLogger().warn( 'Injector already has a mapping for ' + this._mappingID + '.\n ' +
'If you have overridden this mapping intentionally you can use ' +
'"injector.unmap()" prior to your replacement mapping in order to ' +
'avoid seeing this message.' );
}
#end

Expand Down
14 changes: 4 additions & 10 deletions src/hex/di/mapping/MappingConfiguration.hx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import hex.collection.HashMap;
import hex.collection.Locator;
import hex.config.stateful.IStatefulConfig;
import hex.di.IDependencyInjector;
import hex.event.CompositeDispatcher;
import hex.event.IDispatcher;
import hex.module.IModule;
import hex.module.IContextModule;
import hex.service.stateful.IStatefulService;
import hex.util.Stringifier;
import hex.log.HexLog.getLogger;

/**
* ...
Expand All @@ -23,7 +22,7 @@ class MappingConfiguration extends Locator<String, Helper> implements IStatefulC
super();
}

public function configure( injector : IDependencyInjector, dispatcher : IDispatcher<{}>, module : IModule ) : Void
public function configure( injector : IDependencyInjector, module : IContextModule ) : Void
{
var keys = this.keys();
for ( className in keys )
Expand Down Expand Up @@ -58,12 +57,7 @@ class MappingConfiguration extends Locator<String, Helper> implements IStatefulC
{
if ( Std.is( mapped, IStatefulService ) )
{
/*var serviceDispatcher : CompositeDispatcher = ( cast mapped ).getDispatcher();
if ( serviceDispatcher != null )
{
serviceDispatcher.add( dispatcher );
}*/
trace( 'Warning: IStatefulService instances are not added as listener:' + Stringifier.stringify( mapped ) );
getLogger().warn( 'IStatefulService instances are not added as listener:' + Stringifier.stringify( mapped ) );
}

if ( helper.injectInto )
Expand Down
2 changes: 1 addition & 1 deletion src/hex/di/provider/ClassProvider.hx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ClassProvider<T> implements IDependencyProvider<T>
this._type = type;
}

inline public function getResult( injector : IDependencyInjector ) : T
inline public function getResult( injector : IDependencyInjector, target : Class<Dynamic> ) : T
{
return injector.instantiateUnmapped( this._type );
}
Expand Down
2 changes: 1 addition & 1 deletion src/hex/di/provider/SingletonProvider.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SingletonProvider<T> implements IDependencyProvider<T>
this._injector = injector;
}

public function getResult( injector : IDependencyInjector ) : T
public function getResult( injector : IDependencyInjector, target : Class<Dynamic> ) : T
{
#if debug
if ( this._isDestroyed )
Expand Down
2 changes: 1 addition & 1 deletion src/hex/di/provider/ValueProvider.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ValueProvider<T> implements IDependencyProvider<T>
this._injector = injector;
}

inline public function getResult( injector : IDependencyInjector ) : T
inline public function getResult( injector : IDependencyInjector, target : Class<Dynamic> ) : T
{
return this._value;
}
Expand Down
31 changes: 16 additions & 15 deletions src/hex/di/reflect/InjectionUtil.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,45 @@ class InjectionUtil

}

inline public static function applyClassInjection<T>( target : T, injector : Injector, classDescription : ClassDescription ) : T
inline public static function applyClassInjection<T>( target : T, injector : Injector, classDescription : ClassDescription, targetType : Class<Dynamic> ) : T
{
for ( property in classDescription.p )
{
InjectionUtil.applyPropertyInjection( property.p, property.t, property.n, property.o, target, injector );
InjectionUtil.applyPropertyInjection( target, injector, targetType, property.p, property.t, property.n, property.o );
}

for ( method in classDescription.m )
{
InjectionUtil.applyMethodInjection( target, injector, method.a, method.m );
InjectionUtil.applyMethodInjection( target, injector, targetType, method.a, method.m );
}

for ( postConstruct in classDescription.pc )
{
InjectionUtil.applyMethodInjection( target, injector, postConstruct.a, postConstruct.m );
InjectionUtil.applyMethodInjection( target, injector, targetType, postConstruct.a, postConstruct.m );
}

return target;
}

inline public static function applyConstructorInjection<T>( type : Class<T>, injector : Injector, arguments : Array<ArgumentInjection> ) : T
inline public static function applyConstructorInjection<T>( type : Class<T>, injector : Injector, arguments : Array<ArgumentInjection>, targetType : Class<Dynamic> ) : T
{
var args = InjectionUtil.gatherArgs( type, injector, arguments, 'new' );
var args = InjectionUtil.gatherArgs( type, injector, arguments, 'new', targetType );
return Type.createInstance( type, args );
}

inline public static function applyPropertyInjection( propertyName: String,
inline public static function applyPropertyInjection( target : Dynamic,
injector : Injector,
targetType : Class<Dynamic>,
propertyName: String,
propertyType: String,
injectionName: String = '',
isOptional: Bool = false,
target : Dynamic,
injector : Injector ) : Dynamic
isOptional: Bool = false ) : Dynamic
{
var provider = injector.getProvider( propertyType, injectionName );

if ( provider != null )
{
Reflect.setProperty( target, propertyName, provider.getResult( injector ) );
Reflect.setProperty( target, propertyName, provider.getResult( injector, targetType ) );
}
else if ( !isOptional )
{
Expand All @@ -67,13 +68,13 @@ class InjectionUtil
return target;
}

inline public static function applyMethodInjection( target : Dynamic, injector : Injector, arguments : Array<ArgumentInjection>, methodName : String ) : Dynamic
inline public static function applyMethodInjection( target : Dynamic, injector : Injector, targetType : Class<Dynamic>, arguments : Array<ArgumentInjection>, methodName : String ) : Dynamic
{
Reflect.callMethod( target, Reflect.field( target, methodName ), InjectionUtil.gatherArgs( target, injector, arguments, methodName ) );
Reflect.callMethod( target, Reflect.field( target, methodName ), InjectionUtil.gatherArgs( target, injector, arguments, methodName, targetType ) );
return target;
}

inline static function gatherArgs( target : Dynamic, injector : Injector, arguments : Array<ArgumentInjection>, methodName : String ) : Array<Dynamic>
inline static function gatherArgs( target : Dynamic, injector : Injector, arguments : Array<ArgumentInjection>, methodName : String, targetType : Class<Dynamic> ) : Array<Dynamic>
{
var args = [];
for ( arg in arguments )
Expand All @@ -82,7 +83,7 @@ class InjectionUtil

if ( provider != null )
{
args.push( provider.getResult( injector ) );
args.push( provider.getResult( injector, targetType ) );
}
else if ( !arg.o )
{
Expand Down
30 changes: 30 additions & 0 deletions test/hex/di/InjectorTest.hx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import hex.di.mock.injectees.TwoParametersConstructorInjecteeWithGeneric;
import hex.di.mock.injectees.TwoParametersMethodInjectee;
import hex.di.mock.injectees.TwoParametersMethodInjecteeWithGeneric;
import hex.di.mock.injectees.XMLInjectee;
import hex.di.mock.provider.MockDependencyProvider;
import hex.di.mock.types.Clazz;
import hex.di.mock.types.Clazz2;
import hex.di.mock.types.ClazzWithGeneric;
Expand Down Expand Up @@ -858,4 +859,33 @@ class InjectorTest implements IInjectorListener
Assert.isInstanceOf( instance, NamedClassInjecteeWithClassName, "instance should be an instance of 'NamedClassInjecteeWithClassName'" );
Assert.equals( clazzInstance, instance.property, "Named value should have been injected" );
}

@Test( "Test dependency provider" )
public function testDependencyProvider() : Void
{
var instance = new Clazz();
var provider = new MockDependencyProvider<Clazz>(instance);
injector.map( Clazz ).toProvider(provider);

var returnVal = injector.getInstance(Clazz);

Assert.equals(instance, returnVal, "Returned value must come from dependency provider");
Assert.equals(injector, provider.injector, "Injector provided to the dependency provider must be the correct one");
Assert.isNull(provider.target, "Target is unknown so it's supposed to be null");
}

@Test( "Test injection from dependency provider" )
public function testInjectionFromDependencyProvider() : Void
{
var instance = new Clazz();
var provider = new MockDependencyProvider<Clazz>(instance);
injector.map( Clazz, 'Clazz' ).toProvider(provider);

var newInst = injector.instantiateUnmapped(NamedClassInjecteeWithClassName);

Assert.equals(instance, newInst.property, "Returned value must come from dependency provider");
Assert.equals(injector, provider.injector, "Injector provided to the dependency provider must be the correct one");
Assert.equals(NamedClassInjecteeWithClassName, provider.target, "Target should be proper class");
Assert.equals("hex.di.mock.injectees.NamedClassInjecteeWithClassName", provider.className, "Target should be proper class");
}
}
44 changes: 44 additions & 0 deletions test/hex/di/mock/provider/MockDependencyProvider.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package hex.di.mock.provider;

import hex.di.IDependencyInjector;
import hex.di.provider.IDependencyProvider;

/**
* ...
* @author ...
*/
class MockDependencyProvider<T> implements IDependencyProvider<T>
{
var instance:T;

public var target:Class<Dynamic>;
public var injector:IDependencyInjector;

public var className:String;

public function new(instance:T)
{
this.instance = instance;

}


/* INTERFACE hex.di.provider.IDependencyProvider.IDependencyProvider<T> */

public function getResult(injector:IDependencyInjector, target:Class<Dynamic>):T
{
this.injector = injector;
this.target = target;
if(target != null)
{
this.className = Type.getClassName(target);
}
return instance;
}

public function destroy():Void
{

}

}

0 comments on commit ef84ae0

Please sign in to comment.