iOS依赖注入框架系列(一):介绍Typhoon

来源:互联网 发布:淘宝客服是干嘛的? 编辑:程序博客网 时间:2024/06/10 15:45

介绍


作为这一系列的一部分,我不会去考虑依赖性倒置原则,或模式依赖注入的理论 -理所当然地认为读者已经做好充分准备,以确保了解禅宗,并直接进入实践(链接探索中给出的理论帖子的结尾)。 

台风框架 -是最有名的和流行的执行DI容器Objective-C的应用和斯威夫特。 该项目是相当年轻的-第一次提交被做在2012年底,但它已得到了很多球迷 。 特别值得一提它的创始人的积极支持该项目(其中一个,顺便说一句,生活和在鄂木斯克作品) -满足最成熟的问题十分钟,几个小时来讨论整个团队加入。 

为什么我们需要一个台风? 我的答案是一样的缩写 - 国际奥委会。 我答应不进入理论,所以我只是向您推荐Martin Fowler的 。 



让我们来看看一些基本的Typhoon'a包子,这应该足以吸引任何的iOS开发者的注意事项: 
  • 。绝对的,完全原生XML没有,宏或字符串魔法 -完全支持所有这些少数包子,这为我们提供了Xcode中:重构,代码完成,代码检查在编译时。
  • 一个很好的实现模块化 -你可以用任何数量的植物,分为垂直和水平层的工作。
  • 与Storyboard'ami完全集成,可直接在ViewController'y引入任何依赖。
  • 它支持所有的模式依赖注射:注射初始值设定,物业注入和方法注入(而对于后者也有特殊的钩)。
  • 支持注入循环依赖 -为例,对象的ViewController是抱着自己的代表。
  • 摔跤手大的二进制文件可以轻松入睡- 所有模块框架占用只有3000行代码(就像两个普通的ViewController'a)。


与项目基本集成


要显示它是多么容易嵌入在一个干净的台风的应用程序,考虑在其中,我们希望在AppDelegate中的对象startUpConfigurator,谁知道如何正确配置我们的应用程序来实现的情况。 

@interface RIAppDelegate @property (strong, nonatomic) id <RIStartUpConfigurator> startUpConfigurator; @end 

  1. 创建一个子类TyphoonAssembly(谁是我们的DI容器): 

     @interface RIAssembly : TyphoonAssembly - (RIAppDelegate *)appDelegate; @end 

    事实上,这种方法不能申报界面 - 但以教育为目的将离开这里。 

  2. 我们认识到实现RIAssembly: 

     @implementation RIAssembly - (RIAppDelegate *)appDelegate { return [TyphoonDefinition withClass:[RIAppDelegate class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(startUpConfigurator) with:[self startUpConfigurator]]; } } - (id <RIStartUpConfigurator>)startUpConfigurator { return [TyphoonDefinition withClass:[RIStartUpConfiguratorBase class]]; } @end 

    注意,该方法返回到TyphoonDefinition功能的话,不需要额外的注射不进行 -但这样做在未来不受阻碍。 例如,我们可以给他keyWindow应用程序有机会把RootViewController的。 

  3. DI-容器,根据定义,应该是自动化尽可能,我们不希望手动请求从TyphoonAssembly东西。 最好的办法- 使用Info.plist文件。 所有这一切需要我们 - 添加应用程序启动时,应激活某个键名工厂类。 



    这整个配置就完成了。 让我们来看看,在我们成功结束。 

  4. 我们把一个断点的方法-applicationDidFinishLaunching并运行应用程序: 



    配置proinzhektilsya与成功所需类(记得他RIAppDelegate将与他工作在一个特定的协议,通过我们)。

正如你所看到的,台风的基本集成需要几分钟的时间。 此外,该框架可结合在很长一段时间编写的应用程序 - 但在这种情况下,满意的程度将取决于该代码的设计质量。 

但谁是有兴趣在如何配置- 让我们来看看实际使用的情况下台风的项目Rambler.Pochta。 

使用Typhoon在Rambler.Pochte实例


  1. 要创建一个实现特定协议的简单实例,你只需要指定要创建的对象的类。 

     - (id <RCMStoryboardBuilder>)storyboardBuilder { return [TyphoonDefinition withClass:[RCMStoryboardBuilderBase class]]; } 

  2. 为了工作需要RCMAuthorizationPopoverBuilderBase对象storyboardBuilder,创建我们已经学会了。 对于注射它依赖图中,我们只需要调用相应的方法- [自storyboardBuilder。 因此,我们不仅创造类的实例,也是所有安装它的依赖。 

     - (id <RCMPopoverBuilder>)authorizationPopoverBuilder { return [TyphoonDefinition withClass:[RCMAuthorizationPopoverBuilderBase class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(storyboardBuilder) with:[self storyboardBuilder]]; }]; } 

  3. 我们想要的类对象是RCMNetworkLoggerBase辛格尔顿 - 这可以帮助我们拥有财产范围TyphoonDefinition,负责制定的生命周期。 

     - (id <RCMLogger>)networkLogger { return [TyphoonDefinition withClass:[RCMNetworkLoggerBase class] configuration:^(TyphoonDefinition *definition) { definition.scope = TyphoonScopeSingleton; }]; } 

  4. 让我们来看看如何实现台风注射初始值设定。 要使用该服务需要两个设置根据要求- networkClient,能够与网络请求的工作,并credentialsStorage,存储不同的用户凭据。 方法-useInitializer有TyphoonDefinition选择器需要一定的初始化,并且其中所述初始化引入其参数块。 

     - (id <RCMSettingsService>)settingsService { return [TyphoonDefinition withClass:[RCMSettingsServiceBase class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithClient:sessionStorage:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:[self mailXMLRPCClient]]; [initializer injectParameterWith:[self credentialsStorage]]; }]; }]; } 

  5. 现在,让我们来看看注射法的实施。 服务错误可以发送所产生的NSError所有订阅的处理程序。 为了记录所有的原始错误,我们要马上标准处理器签订后创建服务。 

     - (id <RCMErrorService>)errorService { return [TyphoonDefinition withClass:[RCMErrorServiceBase class] configuration:^(TyphoonDefinition *definition) { [definition injectMethod:@selector(addErrorHandler:) parameters:^(TyphoonMethod *method) { [method injectParameterWith:[self defaultErrorHandler]]; }]; }]; } 

  6. 所有ViewController'ov应用必须基于3 - 服务错误处理,这prokidyval所有接收到的对象NSError,一个基本的错误处理,能够正确地处理一些常见的错误代码,以及基础路由器。 为了避免重复的代码为所有控制器,三个依赖注入,我们已经学会了基本TyphoonDefinition。 把它用在其他方法只需要设置属性父。 

     - (UIViewController *)baseViewController { return [TyphoonDefinition withClass:[UIViewController class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(errorService) with:[self.serviceComponents errorService]]; [definition injectProperty:@selector(errorHandler) with:[self baseControllerErrorHandler]]; [definition injectProperty:@selector(router) with:[self baseRouter]]; }]; } - (UIViewController *)userNameTableViewController { return [TyphoonDefinition withClass:[RCMMessageCompositionViewController class] configuration:^(TyphoonDefinition *definition) { definition.parent = [self baseViewController]; [definition injectProperty:@selector(router) with:[self settingsRouter]]; }]; } 

    应当指出的是,台风允许你建立和更复杂的继承链TyphoonDefinition'ov。 

  7. 相反,我们的硬编码的API的网址,我们将它们存储在配置的plist文件。 在这种情况下,下面的台风的帮助-他加载所需的文件,将其转换为场中的原生对象(在这种情况下- NSURL),给我们一个方便的语法来访问字段的配置 - TyphoonConfig(KEY)。 

     - (id)configurer { return [TyphoonDefinition configDefinitionWithName:RCMConfigFileName]; } - (id<RCMRPCClient>)idXMLRPCClient{ return [TyphoonDefinition withClass:[RCMRPCClientBase class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithBaseURL:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:TyphoonConfig(RCMAuthorizationURLKey)]; }]; }]; } 


神话


在那些有兴趣在台风框架表面上,几个神话很普遍,没有根据自身几乎没有理由。 

  1. 高进入壁垒 
    事实上,几个小​​时挖的源代码,文档和项目semplovyh(其中,顺便说一句,有多达三个),你可以了解台风的基本原则,并开始在项目中使用它。 如果你不想深入得多 - 你可以做所有的例子,毫不拖延,到框架集成到你的代码。 

  2. 在调试的强大影响力 
    与我们的代码台风的实际接触点真的是没有那么多,这些关节的开发人员提供了翔实Exception'y。 

  3. 如果台风“的支持,该项目并没有喝 
    台风是好的,我们几乎从未直接交互 - 所以给它了,虽然和将是困难的,但还是可能的 - 只写你的工厂,并将其与代码(甚至手动)整合机制的水平。 

  4. 但是......有svizzling! 
    Objective-C的是著名的运行时间,而不是使用它的能力在这样一个框架 - 至少傻了。 此外,我们使用一个组件作为一个“黑箱”,靠的是事实,所有的耙子已经来到我们1200是相同的星星 。 

  5. 为什么我的台风,当我写我的自行车? 
    台风框架严重降低负责屏幕之间导航时依赖的对象图的创建和传输的代码的数量和复杂性。 此外,它给了我们无缺陷samopisnogo服务定位器集中控制的依赖。 简单工厂,我想,可以写任何阅读器,但随着项目的进展,您将继续面临这种方法的局限性 - ,要么必须实现什么早已深思熟虑和调试,或者牺牲一些功能和项目的表现。

闭幕


我本来打算完全翻译他的讲话在Rambler.iOS印刷样-但写两节意识到材料的一篇文章实在是太多了。 因此,有以下几个系列: 
  • 台风内部框架和模块厂
  • 正在与故事板,测试,自动装配和其他包子台风框架。

相关链接


  • 官方网站台风框架
  • 台风框架的Wiki
  • objc.io#15:依赖注入
  • DI VS DIP VS国际奥委会
  • 依赖倒置原则
  • 控制容器和依赖注入模式反转
0 0
原创粉丝点击