Files
2024-12-09 16:54:19 +08:00

164 lines
4.5 KiB
Objective-C
Executable File

//
// 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 <objc/runtime.h>
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