Created
March 21, 2016 23:02
A simple Service Locator pattern for Swift and Obj-c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#define dep(p) [[Registry shared] resolve: (@protocol(p))] | |
#define reg(c, p) [[Registry shared] register:[c class] forProtocol:@protocol(p)] | |
@interface Registry : NSObject | |
@property (nonatomic, strong) NSMutableDictionary * _Nonnull classRegister; | |
@property (nonatomic, strong) NSMutableDictionary * _Nonnull classInstances; | |
+(instancetype _Nonnull)shared; | |
- (id _Nullable)resolve:(Protocol * _Null_unspecified)aProtocol; | |
- (void)register:(id _Null_unspecified)obj forProtocol:(Protocol * _Null_unspecified)aProtocol; | |
- (void)releaseAllInstances; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Registry.h" | |
#define nssfp(p) NSStringFromProtocol(@protocol(p)) | |
#define nssfc(c) NSStringFromClass([c class]) | |
@implementation Registry : NSObject | |
+ (instancetype _Nonnull)shared | |
{ | |
static dispatch_once_t token; | |
static id sharedInstance = nil; | |
dispatch_once(&token, ^{ | |
sharedInstance = [[[self class] alloc] init]; | |
}); | |
return sharedInstance; | |
} | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self) { | |
_classRegister = [[NSMutableDictionary alloc] init]; | |
_classInstances = [[NSMutableDictionary alloc] init]; | |
} | |
return self; | |
} | |
- (id _Nullable)resolve:(Protocol * _Null_unspecified)aProtocol | |
{ | |
NSString *key = NSStringFromProtocol(aProtocol); | |
id instance = self.classInstances[key]; | |
if([instance conformsToProtocol:aProtocol]) | |
{ | |
return instance; | |
} | |
else | |
{ | |
NSString *className = self.classRegister[key]; | |
instance = [[NSClassFromString(className) alloc]init]; | |
if([instance conformsToProtocol:aProtocol]) | |
{ | |
self.classInstances[key] = instance; | |
return instance; | |
} | |
} | |
return nil; | |
} | |
- (void)register:(id _Null_unspecified)obj forProtocol:(Protocol * _Null_unspecified)aProtocol | |
{ | |
NSString *key = NSStringFromProtocol(aProtocol); | |
NSString *name = NSStringFromClass([obj class]); | |
self.classRegister[key] = name; | |
} | |
- (void)releaseAllInstances | |
{ | |
self.classInstances = [[NSMutableDictionary alloc] init]; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
func dep<T>(aProtocol:Protocol) -> T? | |
{ | |
return Registry.shared().resolve(aProtocol) as? T | |
} | |
func reg(instance: AnyObject, _ aProtocol: Protocol) | |
{ | |
Registry.shared().register(instance, forProtocol:aProtocol) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment