Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #16 from MattesGroeger/master

Resolve circular dependencies between singletons.
  • Loading branch information...
commit c2ef5b129ee46deb7235b77cabc5423010719140 2 parents c7043ef + e636197
@dewind dewind authored
View
14 Objection.xcodeproj/project.pbxproj
@@ -254,6 +254,10 @@
4BED513212AA8BF300CA6B36 /* JSObjectionInjectorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BED512F12AA8BF300CA6B36 /* JSObjectionInjectorEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
4BED513312AA8BF300CA6B36 /* JSObjectionInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BED513012AA8BF300CA6B36 /* JSObjectionInjector.h */; settings = {ATTRIBUTES = (Public, ); }; };
4BED513412AA8BF300CA6B36 /* JSObjectionBindingEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BED513112AA8BF300CA6B36 /* JSObjectionBindingEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D2AAC07E0554694100DB5193 /* CircularDependencySpecs.m in Sources */ = {isa = PBXBuildFile; fileRef = D2AAC07E0554694100DB5192 /* CircularDependencySpecs.m */; };
+ D2AAC07E0554694100DB5194 /* CircularDependencySpecs.m in Sources */ = {isa = PBXBuildFile; fileRef = D2AAC07E0554694100DB5192 /* CircularDependencySpecs.m */; };
+ D2AAC07E0554694100DB5196 /* CircularDependencyFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = D2AAC07E0554694100DB5195 /* CircularDependencyFixtures.m */; };
+ D2AAC07E0554694100DB5197 /* CircularDependencyFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = D2AAC07E0554694100DB5195 /* CircularDependencyFixtures.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -486,6 +490,9 @@
4BF451E21291AD28006EB2D5 /* InjectionErrorsSpecs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InjectionErrorsSpecs.m; sourceTree = "<group>"; };
AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
D2AAC07E0554694100DB518D /* libObjection-StaticLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libObjection-StaticLib.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ D2AAC07E0554694100DB5192 /* CircularDependencySpecs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircularDependencySpecs.m; sourceTree = "<group>"; };
+ D2AAC07E0554694100DB5195 /* CircularDependencyFixtures.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircularDependencyFixtures.m; sourceTree = "<group>"; };
+ D2AAC07E0554694100DB5198 /* CircularDependencyFixtures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularDependencyFixtures.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -809,6 +816,7 @@
4BF45123129197F3006EB2D5 /* Specs */ = {
isa = PBXGroup;
children = (
+ D2AAC07E0554694100DB5192 /* CircularDependencySpecs.m */,
4B42587C13F56EA3006BC001 /* Specs-OSX */,
4B42580C13F56CC0006BC001 /* Specs-iOS */,
4B42571213F5665C006BC001 /* Kiwi */,
@@ -824,6 +832,8 @@
4BF452461291AFEA006EB2D5 /* Helpers */ = {
isa = PBXGroup;
children = (
+ D2AAC07E0554694100DB5198 /* CircularDependencyFixtures.h */,
+ D2AAC07E0554694100DB5195 /* CircularDependencyFixtures.m */,
4BF4514C129198C6006EB2D5 /* SpecHelper.h */,
4BF451AB12919CAD006EB2D5 /* Fixtures.h */,
4BF451AC12919CAD006EB2D5 /* Fixtures.m */,
@@ -1155,6 +1165,8 @@
4B42585813F56D26006BC001 /* NSObject+KiwiVerifierAdditions.m in Sources */,
4B42585913F56D26006BC001 /* NSValue+KiwiAdditions.m in Sources */,
4BE78764145647EF00BD705E /* JSObjectFactory.m in Sources */,
+ D2AAC07E0554694100DB5193 /* CircularDependencySpecs.m in Sources */,
+ D2AAC07E0554694100DB5196 /* CircularDependencyFixtures.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1247,6 +1259,8 @@
4B4258CB13F56F2D006BC001 /* NSObject+KiwiVerifierAdditions.m in Sources */,
4B4258CC13F56F2D006BC001 /* NSValue+KiwiAdditions.m in Sources */,
4BE78765145647EF00BD705E /* JSObjectFactory.m in Sources */,
+ D2AAC07E0554694100DB5194 /* CircularDependencySpecs.m in Sources */,
+ D2AAC07E0554694100DB5197 /* CircularDependencyFixtures.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
35 Source/JSObjectionInjectorEntry.m
@@ -28,10 +28,8 @@ - (id)initWithClass:(Class)theClass lifeCycle:(JSObjectionInstantiationRule)theL
- (id)extractObject
{
- if (self.lifeCycle == JSObjectionInstantiationRuleNormal) {
+ if (self.lifeCycle == JSObjectionInstantiationRuleNormal || !_storageCache) {
return [self buildObject];
- } else if (!_storageCache) {
- _storageCache = [[self buildObject] retain];
}
return _storageCache;
@@ -56,11 +54,16 @@ - (void)notifyObjectThatItIsReady: (id) object
- (id)buildObject
{
- if([self.classEntry respondsToSelector:@selector(objectionRequires)]) {
- NSArray *properties = [self.classEntry performSelector:@selector(objectionRequires)];
- NSMutableDictionary *propertiesDictionary = [NSMutableDictionary dictionaryWithCapacity:properties.count];
- id objectUnderConstruction = [[[self.classEntry alloc] init] autorelease];
-
+ id objectUnderConstruction = [[[self.classEntry alloc] init] autorelease];
+
+ if (self.lifeCycle != JSObjectionInstantiationRuleNormal) {
+ _storageCache = [objectUnderConstruction retain];
+ }
+
+ if ([self.classEntry respondsToSelector:@selector(objectionRequires)]) {
+ NSArray *properties = [self.classEntry performSelector:@selector(objectionRequires)];
+ NSMutableDictionary *propertiesDictionary = [NSMutableDictionary dictionaryWithCapacity:properties.count];
+
for (NSString *propertyName in properties) {
objc_property_t property = JSObjectionUtils.propertyForClass(self.classEntry, propertyName);
JSObjectionPropertyInfo propertyInfo = JSObjectionUtils.findClassOrProtocolForProperty(property);
@@ -73,8 +76,7 @@ - (id)buildObject
}
id theObject = [self.injector getObject:desiredClassOrProtocol];
-
-
+
if(theObject == nil && propertyInfo.type == JSObjectionTypeClass) {
[JSObjection registerClass:desiredClassOrProtocol lifeCycle: JSObjectionInstantiationRuleNormal];
theObject = [_injector getObject:desiredClassOrProtocol];
@@ -83,22 +85,15 @@ - (id)buildObject
reason:[NSString stringWithFormat:@"Cannot find an instance that is bound to the protocol '%@' to assign to the property '%@'", NSStringFromProtocol(desiredClassOrProtocol), propertyName]
userInfo:nil];
}
-
[propertiesDictionary setObject:theObject forKey:propertyName];
}
[objectUnderConstruction setValuesForKeysWithDictionary:propertiesDictionary];
-
- [self notifyObjectThatItIsReady: objectUnderConstruction];
-
- return objectUnderConstruction;
- } else {
- id object = [[[self.classEntry alloc] init] autorelease];
- [self notifyObjectThatItIsReady: object];
- return object;
}
-
+
+ [self notifyObjectThatItIsReady: objectUnderConstruction];
+ return objectUnderConstruction;
}
#pragma mark Class Methods
View
13 Specs/CircularDependencyFixtures.h
@@ -0,0 +1,13 @@
+@class SingletonFoo;
+
+@protocol BarProtocol
+@end
+
+@interface SingletonBar : NSObject <BarProtocol>
+{
+ SingletonFoo *foo;
+}
+
+@property(nonatomic, retain) SingletonFoo *foo;
+
+@end
View
10 Specs/CircularDependencyFixtures.m
@@ -0,0 +1,10 @@
+#import "Objection.h"
+#import "CircularDependencyFixtures.h"
+#import "Fixtures.h"
+
+@implementation SingletonBar
+objection_register_singleton(SingletonBar)
+objection_requires(@"foo")
+
+@synthesize foo;
+@end
View
22 Specs/CircularDependencySpecs.m
@@ -0,0 +1,22 @@
+#import "CircularDependencyFixtures.h"
+#import "SpecHelper.h"
+#import "Fixtures.h"
+
+SPEC_BEGIN(CircularDependencySpecs)
+
+describe(@"Circular Dependency", ^{
+ beforeEach(^{
+ JSObjectionInjector *injector = [JSObjection createInjector];
+ [JSObjection setGlobalInjector:injector];
+ });
+
+ it(@"will be resolved for singletons", ^{
+ SingletonFoo *foo = [[JSObjection globalInjector] getObject:[SingletonFoo class]];
+ SingletonBar *bar = [[JSObjection globalInjector] getObject:[SingletonBar class]];
+
+ assertThat(foo, is(sameInstance(bar.foo)));
+ assertThat(foo.bar, is(sameInstance(bar)));
+ });
+});
+
+SPEC_END
View
10 Specs/Fixtures.h
@@ -65,4 +65,14 @@
@interface JSObjectFactoryHolder : NSObject
@property (nonatomic, retain) JSObjectFactory *objectFactory;
+@end
+
+@class SingletonBar;
+
+@interface SingletonFoo : NSObject
+{
+ SingletonBar *bar;
+}
+@property(nonatomic, retain) SingletonBar *bar;
+
@end
View
7 Specs/Fixtures.m
@@ -1,5 +1,6 @@
#import "Fixtures.h"
#import "Objection.h"
+#import "CircularDependencyFixtures.h"
@implementation Engine
objection_register(Engine)
@@ -56,3 +57,9 @@ @implementation JSObjectFactoryHolder
@synthesize objectFactory;
@end
+@implementation SingletonFoo
+objection_register_singleton(SingletonFoo)
+objection_requires(@"bar")
+
+@synthesize bar;
+@end
Please sign in to comment.
Something went wrong with that request. Please try again.