Skip to content

Commit

Permalink
Merging named arguments feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jdewind committed Mar 26, 2015
2 parents 95b41ca + e7735ff commit 644b27a
Show file tree
Hide file tree
Showing 18 changed files with 495 additions and 107 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Objection is a lightweight dependency injection framework for Objective-C for Ma
* Meta Class Bindings
* Protocol Bindings
* Instance Bindings
* Named Bindings
* Lazily instantiates dependencies
* Eager Singletons
* Initializer Support
Expand Down Expand Up @@ -248,6 +249,36 @@ A class can be scoped as a singleton in a module. Conversely, a registered singl
@end
```

### Named Bindings

Dependencies of the same class or protocol can be identified using the *objection_requires_names* macro, which takes a dictionary of names to properties as a parameter.

#### Example
```objective-c
@interface ShinyCar : NSObject
@property (nonatomic, strong) Headlight *leftHeadlight;
@property (nonatomic, strong) Headlight *rightHeadlight;
@end

@implementation ShinyCar
objection_register(ShinyCar)
objection_requires_names((@{@"LeftHeadlight":@"leftHeadlight", @"RightHeadlight":@"rightHeadlight"}))
@synthesize leftHeadlight, rightHeadlight;
@end

@implementation NamedModule

- (void)configure
{
[self bind:[[Headlight alloc]init] toClass:[Headlight class] named:@"RightHeadlight"];
[self bindClass:[HIDHeadlight class] toClass:[Headlight class] named:@"LeftHeadlight"];

}
@end

```
### Eager Singletons
You can mark registered singleton classes as eager singletons. Eager singletons will be instantiated during the creation of the injector rather than being lazily instantiated.
Expand Down
4 changes: 4 additions & 0 deletions Source/JSObjectionInjector.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
- (id)initWithContext:(NSDictionary *)theGlobalContext andModule:(JSObjectionModule *)theModule;
- (id)initWithContext:(NSDictionary *)theGlobalContext andModules:(NSArray *)theModules;
- (id)getObject:(id)classOrProtocol;
- (id)getObject:(id)classOrProtocol named:(NSString*)name;
- (id)getObjectWithArgs:(id)classOrProtocol, ... NS_REQUIRES_NIL_TERMINATION;
- (id)getObject:(id)classOrProtocol namedWithArgs:(NSString*)name, ... NS_REQUIRES_NIL_TERMINATION;
- (id)getObject:(id)classOrProtocol arguments:(va_list)argList;
- (id)getObject:(id)classOrProtocol named:(NSString*)name arguments:(va_list)argList;
- (id)getObject:(id)classOrProtocol argumentList:(NSArray *)argumentList;
- (id)getObject:(id)classOrProtocol named:(NSString*)name argumentList:(NSArray *)argumentList;
- (id)withModule:(JSObjectionModule *)theModule;
- (id)withModules:(JSObjectionModule *)first, ... NS_REQUIRES_NIL_TERMINATION;
- (id)withModuleCollection:(NSArray *)theModules;
Expand Down
54 changes: 38 additions & 16 deletions Source/JSObjectionInjector.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ - (id)initWithContext:(NSDictionary *)theGlobalContext andModules:(NSArray *)the
return self;
}

- (id)getObject:(id)classOrProtocol {
return [self getObjectWithArgs:classOrProtocol, nil];
}

- (id)getObject:(id)classOrProtocol named:(NSString*)name {
return [self getObject:classOrProtocol namedWithArgs:name, nil];
}

- (id)getObjectWithArgs:(id)classOrProtocol, ... {
va_list va_arguments;
Expand All @@ -73,28 +80,49 @@ - (id)getObjectWithArgs:(id)classOrProtocol, ... {
return object;
}

- (id)getObject:(id)classOrProtocol {
return [self getObjectWithArgs:classOrProtocol, nil];
- (id)getObject:(id)classOrProtocol namedWithArgs:(NSString *)name, ... {
va_list va_arguments;
va_start(va_arguments, name);
id object = [self getObject:classOrProtocol named:name arguments:va_arguments];
va_end(va_arguments);
return object;
}

- (id)getObject:(id)classOrProtocol arguments:(va_list)argList {
return [self getObject:classOrProtocol named:nil arguments:argList];
}

- (id)getObject:(id)classOrProtocol named:name arguments:(va_list)argList {
NSArray *arguments = JSObjectionUtils.transformVariadicArgsToArray(argList);
return [self getObject:classOrProtocol named:name argumentList:arguments];
}

- (id)getObject:(id)classOrProtocol argumentList:(NSArray *)argumentList {
@synchronized(self) {
return [self getObject:classOrProtocol named:nil argumentList:argumentList];
}

- (id)getObject:(id)classOrProtocol named:(NSString*)name argumentList:(NSArray *)argumentList {
@synchronized(self) {
if (!classOrProtocol) {
return nil;
}
NSString *key = nil;
BOOL isClass = class_isMetaClass(object_getClass(classOrProtocol));

if (isClass) {
key = NSStringFromClass(classOrProtocol);
} else {
key = [NSString stringWithFormat:@"<%@>", NSStringFromProtocol(classOrProtocol)];
}



if (name)
{
key = [NSString stringWithFormat:@"%@:%@",key,name];
}

id<JSObjectionEntry> injectorEntry = [_context objectForKey:key];
injectorEntry.injector = self;

if (!injectorEntry) {
id<JSObjectionEntry> entry = [_globalContext objectForKey:key];
if (entry) {
Expand All @@ -107,21 +135,15 @@ - (id)getObject:(id)classOrProtocol argumentList:(NSArray *)argumentList {
[_context setObject:injectorEntry forKey:key];
}
}

if (classOrProtocol && injectorEntry) {
return [injectorEntry extractObject:argumentList];
}

return nil;
}

return nil;

}

- (id)getObject:(id)classOrProtocol arguments:(va_list)argList {
NSArray *arguments = JSObjectionUtils.transformVariadicArgsToArray(argList);
return [self getObject:classOrProtocol argumentList:arguments];
return nil;
}

- (id)objectForKeyedSubscript: (id)key {
Expand Down
18 changes: 17 additions & 1 deletion Source/JSObjectionModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,37 @@
@property (nonatomic, readonly) NSSet *eagerSingletons;

- (void)bind:(id)instance toClass:(Class)aClass;
- (void)bind:(id)instance toClass:(Class)aClass named:(NSString *)name;
- (void)bind:(id)instance toProtocol:(Protocol *)aProtocol;
- (void)bind:(id)instance toProtocol:(Protocol *)aProtocol named:(NSString *)name;
- (void)bindMetaClass:(Class)metaClass toProtocol:(Protocol *)aProtocol;
- (void)bindProvider:(id<JSObjectionProvider>)provider toClass:(Class)aClass;
- (void)bindProvider:(id<JSObjectionProvider>)provider toClass:(Class)aClass named:(NSString *)name;
- (void)bindProvider:(id<JSObjectionProvider>)provider toProtocol:(Protocol *)aProtocol;
- (void)bindProvider:(id<JSObjectionProvider>)provider toProtocol:(Protocol *)aProtocol named:(NSString *)name;
- (void)bindProvider:(id<JSObjectionProvider>)provider toClass:(Class)aClass inScope:(JSObjectionScope)scope;
- (void)bindProvider:(id<JSObjectionProvider>)provider toClass:(Class)aClass inScope:(JSObjectionScope)scope named:(NSString *)name;
- (void)bindProvider:(id<JSObjectionProvider>)provider toProtocol:(Protocol *)aProtocol inScope:(JSObjectionScope)scope;
- (void)bindProvider:(id<JSObjectionProvider>)provider toProtocol:(Protocol *)aProtocol inScope:(JSObjectionScope)scope named:(NSString *)name;
- (void)bindClass:(Class)aClass toProtocol:(Protocol *)aProtocol;
- (void)bindClass:(Class)aClass toProtocol:(Protocol *)aProtocol named:(NSString*)name;
- (void)bindClass:(Class)aClass toProtocol:(Protocol *)aProtocol inScope:(JSObjectionScope)scope named:(NSString*)name;
- (void)bindClass:(Class)aClass toClass:(Class)toClass;
- (void)bindClass:(Class)aClass toClass:(Class)toClass named:(NSString*)name;
- (void)bindClass:(Class)aClass toClass:(Class)toClass inScope:(JSObjectionScope)scope named:(NSString*)name;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toClass:(Class)aClass;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toClass:(Class)aClass named:(NSString *)name;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toProtocol:(Protocol *)aProtocol;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toProtocol:(Protocol *)aProtocol named:(NSString *)name;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toClass:(Class)aClass inScope:(JSObjectionScope)scope;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toClass:(Class)aClass inScope:(JSObjectionScope)scope named:(NSString *)name;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toProtocol:(Protocol *)aProtocol inScope:(JSObjectionScope)scope;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toProtocol:(Protocol *)aProtocol inScope:(JSObjectionScope)scope named:(NSString *)name;
- (void)bindClass:(Class)aClass inScope:(JSObjectionScope)scope;
- (void)registerEagerSingleton:(Class)aClass;
- (BOOL)hasBindingForClass:(Class)aClass;
- (BOOL)hasBindingForClass:(Class)aClass withName:(NSString*)name;
- (BOOL)hasBindingForProtocol:(Protocol *)protocol;
- (BOOL)hasBindingForProtocol:(Protocol *)protocol withName:(NSString*)name;
- (void)configure;
@end
@end
Loading

0 comments on commit 644b27a

Please sign in to comment.