When using a hand made container/injector responsible for creating and managing the lifecycle of the objects in my graph I use the following pattern(I read in an article about DIY DI in ObjC):
Let's say we have a root view controller that wants to present another one(let's call it detail view controller) passing some data to it. What I normally do is to inject a provider block that takes the data as an argument and returns a new view controller to present. Here is some code...
@implementation RootViewController
{
UIViewController (^detailViewControllerProvider)(SomeData *someData);
}
- (id) initWithDetailViewControllerProvider:(UIViewController (^)(SomeData *someData))detailViewControllerProvider
{
//...
_detailViewControllerProvider = detailViewControllerProvider;
//...
}
// ...
- (void) presentDetailViewControllerWithData:(SomeData *)someData
{
UIViewController *detailViewController = _detailViewControllerProvider(someData);
[self presentViewController:detailViewController animated:YES completion:nil];
}
@end
I could use a factory class as well but this way I avoid creating a new class just creating the provider block in my container class.
The problem comes when I want to use Typhoon as a DI container. How can I use the same pattern? In my detail view controller I am injecting other things and I want to keep using constructor injection, and prefer if it is created by the component factory, not by me. I could create a factory class to create the detail VC, injecting in it(the factory) the dependencies I want to inject later in my detail VC, but it seems too much work comparing to the block based solution.
I don't want to access my component factory from the root view controller and neither use setter injection for someData.
Is there any solution for this?
I would go with a factory.
It seems like a little overhead, but if you do TDD, it will drastically simplify your life as your can easily mock a factory and test your controller in isolation.
It will also work well with a typhoon.