{"id":18809983,"url":"https://github.com/aryaxt/ocinjection","last_synced_at":"2025-04-13T20:30:40.055Z","repository":{"id":62449254,"uuid":"9739113","full_name":"aryaxt/OCInjection","owner":"aryaxt","description":"Dependency Injection framework for Objective C","archived":false,"fork":false,"pushed_at":"2014-03-03T16:32:14.000Z","size":812,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-31T15:47:13.883Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aryaxt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-04-29T01:34:06.000Z","updated_at":"2019-06-16T10:28:59.000Z","dependencies_parsed_at":"2022-11-02T01:01:19.711Z","dependency_job_id":null,"html_url":"https://github.com/aryaxt/OCInjection","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aryaxt%2FOCInjection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aryaxt%2FOCInjection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aryaxt%2FOCInjection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aryaxt%2FOCInjection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aryaxt","download_url":"https://codeload.github.com/aryaxt/OCInjection/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223602932,"owners_count":17172005,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T23:18:24.608Z","updated_at":"2024-11-07T23:18:26.013Z","avatar_url":"https://github.com/aryaxt.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"OCInjection\n==========\n\nDI framework for Objective C. This framework is still under development, and it is not meant to be used in production yet.\n\nOCInjection supports both property injection and constructor injection.\nIn order to inject a property you need to mark the property as @dynamic. \n\nProperty injection is required on root level (ex:Injecting property in a ViewContorller).\nOn lower levels you can decide to either go with property injection or constructor injection, but constructor injection is always preferred.\n\nConfiguring DI Container\n----------\nIn order to configure binding create a new class inheriting from 'DIAbstractModule', and implement configure 'method'\n```objective-c\n#import \"DIAbstractModule.h\"\n\n@interface DIConfig : DIAbstractModule\n\n@end\n```\n```objective-c\n@implementation DIConfig\n\n- (void)configure\n{\n        // Binding protocol to a class, and mamarking it a singleton object\n        // Since constrcutor is not defined the standard init method will be used for initialization\n        [self bindProtocol:@protocol(ServiceClientProtocl) toClass:[ServiceClient class] asSingleton:YES];\n        \n        // Binding a protocol to a class, and defining a constructor\n        // Objective c doesn't preserve method argument types (Class info) at runtime\n        // So you must provide the type of parameters when binding\n\t[[[self bindProtocol:@protocol(GithubClientProtocol) toClass:[GithubClient class]] withConstructor]\n\t\tinitWithServiceClient:Inject(@protocol(ServiceClientProtocl))];\n}\n\n@end\n```\n```objective-c\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    DIConfig *config = [[DIConfig alloc] init];\n    [[DIInjector sharedInstance] setDefaultModule:config];\n\t\n    return YES;\n}\n```\nUsing DI\n----------\n```objective-c\n@interface ViewController : UIViewController\n\n@property (nonatomic, strong) IBOutlet UIWebView *webView;\n\n@end\n```\n```objective-c\n@interface ViewController()\n@property (nonatomic, strong) id \u003cGithubClientProtocol\u003e githubClient;\n@end\n\n@implementation ViewController\n@synthesize webView;\n@dynamic githubClient;\n\n- (void)viewDidLoad\n{\n   [super viewDidLoad];\n   \n   [self.githubClient fetchDataByUsername:@\"aryaxt\"];\n}\n\n@end\n```\n\nMocking Dependencies for Unit Testing\n----------\n```objective-c\n@implementation DIMockConfig\n\n- (void)configure\n{\n\tOCMockObject *githubClient = [OCMockObject mockForProtocol:@protocol(GithubClientProtocol)];\n\tOCMockObject *serviceClient = [OCMockObject mockForProtocol:@protocol(ServiceClientProtocol)];\n\t\n\t[self bindProtocol:@protocol(ServiceClientProtocol) toInstance:serviceClient];\n\t[self bindProtocol:@protocol(GithubClientProtocol) toInstance:githubClient];\n}\n\n@end\n```\nSample Unit Test\n----------\n```objective-c\n@interface ViewControllerTests : SenTestCase\n\n@property (nonatomic, strong) ViewController *viewController;\n\n@end\n```\n```objective-c\n@interface ViewControllerTests()\n@property (nonatomic, strong) id \u003cGithubClientProtocol\u003e githubClient;\n@end\n\n@implementation ViewControllerTests\n@dynamic githubClient;\n@synthesize viewController;\n\n#pragma mark - Setup \u0026 TearDown -\n\n- (void)setUp\n{\n    [super setUp];\n    \n\tDIMockConfig *module = [[DIMockConfig alloc] init];\n\t[[DIInjector sharedInstance] setDefaultModule:module];\n\t\n    self.viewController = [[ViewController alloc] init];\n}\n\n- (void)tearDown\n{\n    self.viewController =  nil;\n    \n    [super tearDown];\n}\n\n#pragma mark - Tests -\n\n- (void)testShouldFetchDataWithCorrectUsername\n{\n       // Since we bind GithubClientProtocol to an instance\n       // The instance injected in viewController is the same as the one injected in test file\n       // So we can mock the object and test it without having to make it a public property\n\n\tstatic NSString *expectedUsername = @\"DependencyInjearyaxtction\";\n\t[[(OCMockObject *)self.githubClient expect] fetchDataByUsername:expectedUsername];\n\t[self.viewController view]; // Trigger viewDidLoad\n\t[(OCMockObject *)self.githubClient verify];\n}\n\n@end\n```\nIn-Line Dependency Resolving\n----------\n```objective-c\n// Resolving Protocol\nid \u003cGoogleClientProtocol\u003e googleClient = [[DIInjector sharedInstance] resolveForProtocol:@protocol(GoogleClientProtocol)];\n\n// Resolving Class\nYahooClient *yahooClient = [[DIInjector sharedInstance] resolveForClass:[YahooClient class]];\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faryaxt%2Focinjection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faryaxt%2Focinjection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faryaxt%2Focinjection/lists"}