I'm a little confused between these two capabilities. Can the same functionality be achieved by either approach. Why create a protocol and allow typhoon to auto generate the implementation if I can just call an assembly with my run time arguments and have that spit out the fully injected object graph?
It seems to me that the assembly with run-time arguments should be the preferred approach. With this I won't have to create large, verbose constructors if I have multiple dependencies that need injected.
For example I can define a factory like this:
@protocol AWDailyDetailsPagingViewControllerFactory <NSObject>
@property (nonatomic, strong, readonly) AWStripViewController *stripViewController;
@property (nonatomic, strong, readonly) AWDailyDetailsDataSource *dailyDetailsDataSource;
@property (nonatomic, strong, readonly) AWLocationListViewController *locationListViewController;
@property (nonatomic, strong, readonly) id<AWPresentationController> presentationController;
@property (nonatomic, strong, readonly) AWPullToRefreshGestureHandler *pullToRefreshGestureHandler;
- (AWDailyDetailsPagingViewController *)dailyDetailsPagingViewControllerWithUserLocation:(AWUserLocation *)userLocation initialLayoutModel:(AWDailyDetailsViewControllerLayoutModel *)initialLayoutModel;
@end
Then I would be required to create a constructor in my ViewController like this:
- (instancetype)initWithStripViewController:(AWStripViewController *)stripViewController
dailyDetailsDataSource:(AWDailyDetailsDataSource *)dailyDetailsDataSource
locationListViewController:(AWLocationListViewController *)locationListViewController
presentationController:(id<AWPresentationController>)presentationController
pullToRefreshGestureHandler:(AWPullToRefreshGestureHandler *)pullToRefreshGestureHandler
userLocation:(AWUserLocation *)userLocation
initialLayoutModel:(AWDailyDetailsViewControllerLayoutModel *)initialLayoutModel;
Using this factory protocol is super clean and elegant, so there's no problem there:
[self.dailyDetailsPagingViewControllerFactory dailyDetailsPagingViewControllerWithUserLocation:userLocation initialLayoutModel:initialLayoutModel];
But boy that constructor is just a bit ugly. It seems to me with run-time arguments and assemblies I can avoid that constructor by just injecting into the properties (which I have defined anyway). For example, I believe my assembly would look something like this:
- (id)dailyDetailsPagingViewControllerWithUserLocation:(AWUserLocation *)userLocation initialLayoutModel:(AWDailyDetailsViewControllerLayoutModel *)layoutModel {
return [TyphoonDefinition withClass:[AWDailyDetailsPagingViewController class] configuration:^(TyphoonDefinition* definition) {
[definition injectProperty:@selector(stripViewController) with:[self horizontalStripViewController]];
[definition injectProperty:@selector(dailyDetailsDataSource) with:[self dailyDetailsDataSource]];
[definition injectProperty:@selector(locationListViewController) with:[self.navigationAssembly locationListViewController]];
[definition injectProperty:@selector(pullToRefreshGestureHandler) with:[self.navigationAssembly pullToRefreshGestureHandler]];
[definition injectProperty:@selector(presentationController) with:[self.navigationAssembly presentationController]];
[definition injectProperty:@selector(userLocation) with:userLocation];
[definition injectProperty:@selector(layoutModel) with:layoutModel];
}];
}
Everything is now contained inside the assembly and at runtime I should see the same result as that of the Factory Provider.
So am I on the right track here? Do these two features provide the same functionality? Which one should be used in most cases? Does it matter?
Thanks for any comments and answers!
These two features are essentially compatible.
We recommend using the newer run-time arguments for the following reasons:
As it happens, I've created a ticket today, to debate if we can consolidate the two features, and provide just a single solution: