简体   繁体   中英

Typhoon injection with Run-time Arguments or Factory Providers

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:

  • Easier to configure.
  • Can propagate arguments down into dependencies
  • Works with circular dependencies
  • No protocol required, just assembly interface. Though you can create one if you wish.

As it happens, I've created a ticket today , to debate if we can consolidate the two features, and provide just a single solution:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM