diff --git a/Source/Definition/Initializer/Internal/TyphoonInitializer+InstanceBuilder.m b/Source/Definition/Initializer/Internal/TyphoonInitializer+InstanceBuilder.m index 93e948cd0..4a20c1fdc 100644 --- a/Source/Definition/Initializer/Internal/TyphoonInitializer+InstanceBuilder.m +++ b/Source/Definition/Initializer/Internal/TyphoonInitializer+InstanceBuilder.m @@ -123,7 +123,7 @@ - (void)configureInvocation:(NSInvocation*)invocation withFactory:(TyphoonCompon if (parameter.type == TyphoonParameterInjectionTypeReference) { TyphoonParameterInjectedByReference* byReference = (TyphoonParameterInjectedByReference*) parameter; - [[factory stack] peekForKey:byReference.reference]; //Raises circular dependencies exception if already initializing. + [[factory stack] peekInstanceForKey:byReference.reference]; //Raises circular dependencies exception if already initializing. id reference = [factory componentForKey:byReference.reference]; [invocation setArgument:&reference atIndex:parameter.index + 2]; } diff --git a/Source/Factory/Internal/TyphoonCallStack.h b/Source/Factory/Internal/TyphoonCallStack.h index 9793a5b7e..99e1dac78 100644 --- a/Source/Factory/Internal/TyphoonCallStack.h +++ b/Source/Factory/Internal/TyphoonCallStack.h @@ -21,11 +21,13 @@ - (TyphoonStackElement*)pop; -/** -* Peeks for the given key. If the key represents an instance undergoing initializer injection, raises a circular init exception. -*/ - (TyphoonStackElement*)peekForKey:(NSString*)key; +/** + * Peeks instance for the given key. If the key represents an instance undergoing initializer injection, raises a circular init exception. + */ +- (id)peekInstanceForKey:(NSString *)key; + - (BOOL)isResolvingKey:(NSString*)key; - (BOOL)isEmpty; diff --git a/Source/Factory/Internal/TyphoonCallStack.m b/Source/Factory/Internal/TyphoonCallStack.m index 153d34737..1685531a9 100644 --- a/Source/Factory/Internal/TyphoonCallStack.m +++ b/Source/Factory/Internal/TyphoonCallStack.m @@ -72,18 +72,25 @@ - (TyphoonStackElement*)peekForKey:(NSString*)key { if ([item.key isEqualToString:key]) { - if ([item isInitializingInstance]) - { - [NSException raise:@"CircularInitializerDependence" - format:@"The object for key %@ is currently initializing, but was specified as init dependency in another object", - item.key]; - } return item; } } return nil; } +- (id)peekInstanceForKey:(NSString*)key +{ + TyphoonStackElement* stackElement = [self peekForKey:key]; + + if ([stackElement isInitializingInstance]) { + [NSException raise:@"CircularInitializerDependence" + format:@"The object for key %@ is currently initializing, but was specified as init dependency in another object", + stackElement.key]; + } + + return stackElement.instance; +} + - (BOOL)isEmpty { diff --git a/Source/Factory/Internal/TyphoonComponentFactory+InstanceBuilder.m b/Source/Factory/Internal/TyphoonComponentFactory+InstanceBuilder.m index 88a4c75c2..23bfea8d8 100644 --- a/Source/Factory/Internal/TyphoonComponentFactory+InstanceBuilder.m +++ b/Source/Factory/Internal/TyphoonComponentFactory+InstanceBuilder.m @@ -129,10 +129,10 @@ - (void)injectAssemblyOnInstance:(id )instance - (id)buildSharedInstanceForDefinition:(TyphoonDefinition*)definition { - TyphoonStackElement* stackElement = [_stack peekForKey:definition.key]; - if (stackElement) + id instance = [_stack peekInstanceForKey:definition.key]; + if (instance) { - return stackElement.instance; + return instance; } return [self buildInstanceWithDefinition:definition]; } diff --git a/Tests/Factory/Shared/TyphoonSharedComponentFactoryTests.m b/Tests/Factory/Shared/TyphoonSharedComponentFactoryTests.m index e9499604c..2a3072e10 100644 --- a/Tests/Factory/Shared/TyphoonSharedComponentFactoryTests.m +++ b/Tests/Factory/Shared/TyphoonSharedComponentFactoryTests.m @@ -260,27 +260,15 @@ - (void)test_resolves_chains_of_circular_dependencies_of_singletons_injected_by_ assertThat(notSingletonA.dependencyOnA, is(singletonA)); } -- (void)test_initializer_injected_component_raises_exception_for_circular_dependency +- (void)test_initializer_injected_component_is_correctly_resolved_in_circular_dependency { - @try - { - PrototypeInitInjected* initializerInjected = [_circularDependenciesFactory componentForType:[PrototypeInitInjected class]]; - STFail(@"Should've raised exception"); - } - @catch (NSException* e) - { - assertThat([e description], equalTo( - @"The object for key prototypeInitInjected is currently initializing, but was specified as init dependency in another object")); - } - - //FIXME: Old test: We were leaning towards supporting circular deps in initializers. . decision? -// PrototypeInitInjected* initializerInjected = [_circularDependenciesFactory componentForType:[PrototypeInitInjected class]]; -// PrototypePropertyInjected* propertyInjected = [_circularDependenciesFactory componentForType:[PrototypePropertyInjected class]]; -// // should be expected class, but not same instance -// assertThat(initializerInjected.prototypePropertyInjected, instanceOf([PrototypePropertyInjected class])); -// assertThat(initializerInjected.prototypePropertyInjected, isNot(propertyInjected)); -// assertThat(propertyInjected.prototypeInitInjected, instanceOf([PrototypeInitInjected class])); -// assertThat(propertyInjected.prototypeInitInjected, isNot(initializerInjected)); + PrototypeInitInjected* initializerInjected = [_circularDependenciesFactory componentForType:[PrototypeInitInjected class]]; + PrototypePropertyInjected* propertyInjected = [_circularDependenciesFactory componentForType:[PrototypePropertyInjected class]]; + // should be expected class, but not same instance + assertThat(initializerInjected.prototypePropertyInjected, instanceOf([PrototypePropertyInjected class])); + assertThat(initializerInjected.prototypePropertyInjected, isNot(propertyInjected)); + assertThat(propertyInjected.prototypeInitInjected, instanceOf([PrototypeInitInjected class])); + assertThat(propertyInjected.prototypeInitInjected, isNot(initializerInjected)); } /* ====================================================================================================================================== */