I found nice tutorial that show how dependency injection works.
But I still can't understand for which purposes we need it?
It was understandable for me how to use abstraction, but I don't understand for which purposes we need this code below:
- (BNRItemsViewController *)itemsViewController {
return [TyphoonDefinition withClass:[BNRItemsViewController class] configuration:^(TyphoonDefinition *definition) {
[definition injectProperty:@selector(itemStore) with:[self store]];
}];
}
- (id<BNRItemStore>)store {
return [TyphoonDefinition withClass:[BNRItemStoreImpl class] configuration:^(TyphoonDefinition *definition) {
[definition useInitializer:@selector(sharedStore) parameters:^(TyphoonMethod *initializer) {
definition.scope = TyphoonScopeLazySingleton;
}];
}];
}
What is actually itemsViewController
and how it will be called and how we get the items without setting it outside.
What the main goal for injection? So I can seems simple do this:
BNRItemsViewController *vc = ...
vc.itemStore = [BNRItemStore ...]
what is the advantage for me using library?
There are a couple advantages that Typhoon gives you:
1) In the case of:
BNRItemsViewController *vc = ...
vc.itemStore = [BNRItemStore ...]
you are manually instantiating the view controller, and then setting the itemStore to a concrete class (BNItemStore) which is now hard-coded into this and any other class that instantiates BNRItemsViewController. But Typhoon injects the itemStore property automatically at initialization, regardless of where that initialization happens. Even if a storyboard segue initializes the BNRItemsViewController class (no manual instantiation in your code), it will return from initialization with the itemStore property already set automatically by the dependency injection framework. And it will be injected with the same value every place it is instantiated, without your code having to set that property to a hard-coded concrete class every time.
2) You don't have to change your code in one or more places to change what concrete implementation of the BNRItemStore protocol is passed into the BNRItemsViewController. Instead, you define what set of concrete injections will occur throughout the app in your info.plist, where you specify the Typhoon assembly that will be used. This means that you can have a test assembly, a staging assembly, a prod assembly, and have all the proper dependencies required for each of those scenarios injected throughout the app, controlled from a single location and not hard-coded into your actual source code. In other words, you can change the entire graph of what dependencies will be used for any given build of your app without touching the source code, and based on what type of context the app is running in (test, dev, release, etc.)