// // TAServiceManager.m // ThinkingSDK.default-Base-Core-Extension-Router-Util-iOS // // Created by wwango on 2022/10/7. // #import "TAServiceManager.h" #import "TAContext.h" #import "TAAnnotation.h" #import static const NSString *kTAService = @"service"; static const NSString *kTAImpl = @"impl"; @interface TAServiceManager() @property (nonatomic, strong) NSMutableDictionary *allServicesDict; @property (nonatomic, strong) NSRecursiveLock *lock; @end @implementation TAServiceManager + (instancetype)sharedManager { static id sharedManager = nil; static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ sharedManager = [[self alloc] init]; }); return sharedManager; } - (void)registerLocalServices { } - (void)registerService:(Protocol *)service implClass:(Class)implClass { NSParameterAssert(service != nil); NSParameterAssert(implClass != nil); if (![implClass conformsToProtocol:service]) { if (self.enableException) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ module does not comply with %@ protocol", NSStringFromClass(implClass), NSStringFromProtocol(service)] userInfo:nil]; } return; } if ([self checkValidService:service]) { if (self.enableException) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ protocol has been registed", NSStringFromProtocol(service)] userInfo:nil]; } return; } NSString *key = NSStringFromProtocol(service); NSString *value = NSStringFromClass(implClass); if (key.length > 0 && value.length > 0) { [self.lock lock]; [self.allServicesDict addEntriesFromDictionary:@{key:value}]; [self.lock unlock]; } } - (id)createService:(Protocol *)service { return [self createService:service withServiceName:nil]; } - (id)createService:(Protocol *)service withServiceName:(NSString *)serviceName { return [self createService:service withServiceName:serviceName shouldCache:YES]; } - (id)createService:(Protocol *)service withServiceName:(NSString *)serviceName shouldCache:(BOOL)shouldCache { if (!serviceName.length) { serviceName = NSStringFromProtocol(service); } id implInstance = nil; if (![self checkValidService:service]) { if (self.enableException) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ protocol does not been registed", NSStringFromProtocol(service)] userInfo:nil]; } } NSString *serviceStr = serviceName; if (shouldCache) { id protocolImpl = [[TAContext shareInstance] getServiceInstanceFromServiceName:serviceStr]; if (protocolImpl) { return protocolImpl; } } Class implClass = [self serviceImplClass:service]; if ([[implClass class] respondsToSelector:@selector(singleton)]) { if ([[implClass class] performSelector:@selector(singleton)]) { if ([[implClass class] respondsToSelector:@selector(shareInstance)]) implInstance = [[implClass class] shareInstance]; else implInstance = [[implClass alloc] init]; if (shouldCache) { [[TAContext shareInstance] addServiceWithImplInstance:implInstance serviceName:serviceStr]; return implInstance; } else { return implInstance; } } } return [[implClass alloc] init]; } #pragma mark - private - (Class)serviceImplClass:(Protocol *)service { NSString *serviceImpl = [[self servicesDict] objectForKey:NSStringFromProtocol(service)]; if (serviceImpl.length > 0) { return NSClassFromString(serviceImpl); } return nil; } - (BOOL)checkValidService:(Protocol *)service { NSString *serviceImpl = [[self servicesDict] objectForKey:NSStringFromProtocol(service)]; if (serviceImpl.length > 0) { return YES; } return NO; } - (NSMutableDictionary *)allServicesDict { if (!_allServicesDict) { _allServicesDict = [NSMutableDictionary dictionary]; } return _allServicesDict; } - (NSRecursiveLock *)lock { if (!_lock) { _lock = [[NSRecursiveLock alloc] init]; } return _lock; } - (NSDictionary *)servicesDict { [self.lock lock]; NSDictionary *dict = [self.allServicesDict copy]; [self.lock unlock]; return dict; } @end