台风注射与运行时参数或工厂提供商

时间:2014-05-29 14:32:15

标签: objective-c dependency-injection typhoon

我对这两种能力感到有些困惑。任何一种方法都可以实现相同的功能。为什么我创建一个协议并允许台风自动生成实现,如果我可以用我的运行时参数调用一个程序集并让它吐出完全注入的对象图?

在我看来,具有运行时参数的程序集应该是首选方法。有了这个,如果我有多个需要注入的依赖项,我就不必创建大型的详细构造函数。

例如,我可以定义这样的工厂:

@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

然后我需要在我的ViewController中创建一个构造函数,如下所示:

- (instancetype)initWithStripViewController:(AWStripViewController *)stripViewController
                     dailyDetailsDataSource:(AWDailyDetailsDataSource *)dailyDetailsDataSource
                 locationListViewController:(AWLocationListViewController *)locationListViewController
                     presentationController:(id<AWPresentationController>)presentationController
                pullToRefreshGestureHandler:(AWPullToRefreshGestureHandler *)pullToRefreshGestureHandler
                               userLocation:(AWUserLocation *)userLocation
                         initialLayoutModel:(AWDailyDetailsViewControllerLayoutModel *)initialLayoutModel;

使用这个工厂协议非常干净和优雅,所以没有问题:

[self.dailyDetailsPagingViewControllerFactory dailyDetailsPagingViewControllerWithUserLocation:userLocation initialLayoutModel:initialLayoutModel];

但是那个构造函数的男孩有点难看。在我看来,运行时参数和程序集我可以通过注入属性(我已经定义了)来避免该构造函数。例如,我相信我的装配看起来像这样:

- (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];
    }];
}

现在所有东西都包含在程序集中,在运行时我应该看到与Factory Provider相同的结果。

我在这里走在正确的轨道上吗?这两个功能是否提供相同的功能?在大多数情况下应该使用哪一个?这有关系吗?

感谢您的任何意见和解答!

1 个答案:

答案 0 :(得分:1)

这两个功能基本上是兼容的。

我们建议使用较新的运行时参数,原因如下:

  • 易于配置。
  • 可以将参数传播到依赖项
  • 使用循环依赖
  • 无需协议,只需汇编界面。虽然如果你愿意,你可以创建一个。

碰巧,我是created a ticket today,辩论我们是否可以整合这两个功能,并提供一个解决方案: