网络科技

    今日:818| 主题:244863
收藏本版
互联网、科技极客的综合动态。

[其他] Activities Subcomponents Multibinding in Dagger 2

[复制链接]
另一种晚安 发表于 2016-10-19 03:18:03
61 1

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
A couple months ago, during    MCE³conference, Gregory Kick in his    presentationshowed a new concept of providing Subcomponents (e.g. to Activities). New approach should give us a way to create ActivitySubcomponent without having AppComponent object reference (which used to be a factory for Activities Subcomponents). To make it real we had to wait for a new release of Dagger:    version 2.7.  
  The problem

  Before Dagger 2.7, to create Subcomponent (e.g.    MainActivityComponentwhich is Subcomponent of    AppComponent) we had to declare its factory in parent Component:  
  Thanks to this declaration we Dagger knows that    MainActivityComponenthas access to dependencies from    AppComponent.  
  Having this, injection in    MainActivitylooks similar to:  
  The problems with this code are:
  
       
  •       Activity depends on        AppComponent(returned by        ((MyApplication) getApplication()).getComponent())— whenever we want to create Subcomponent, we need to have access to parent Component object.      
       
  •               AppComponenthas to have declared factories for all Subcomponents (or their builders), e.g.:        MainActivityComponent plus(MainActivityComponent.ModuleImpl module);.      
      
  Modules.subcomponents

  Starting from Dagger 2.7 we have new way to declare parents of Subcomponents.    @Moduleannotation has optionalsubcomponents field which gets list of Subcomponents classes, which should be children of the Component in which this module is installed.  
  Example:

          ActivityBindingModuleis installed in      AppComponent. It means that both:      MainActivityComponentand      SecondActivityComponentare Subcomponents of      AppComponent.   
    Subcomponents declared in this way don’t have to be declared explicitly in      AppComponent(like was done in first code listing in this post).   
    Activities Multibinding

  Let’s see how we could use    Modules.subcomponentsto build Activities Multibinding and get rid of AppComponent object passed to Activity (it’s also explained at the end of this    presentation). I’ll go only through the most important pieces in code. Whole implementation is available on Github:    Dagger2Recipes-ActivitiesMultibinding.  
  Our app contains two simple screens:    MainActivityand    SecondActivity. We want to be able to provide Subcomponents to both of them without passing    AppComponentobject.  
  Let’s start from building a base interface for all Activity Components builders:
  Example Subcomponent:    MainActivityComponentcould look like this:  
  Now we would like to have    Mapof Subcomponents builders to be able to get intended builder for each Activity class. Let’s use    Multibindingfeature for this:  
      ActivityBindingModuleis installed in    AppComponent. Like it was explained, thanks to this    MainActivityComponentand    SecondActivityComponentwill be Subcomponent of    AppComponent.  
  Now we can inject Map of    Subcomponentsbuilder (e.g. to    MyApplicationclass):  
  To have additional abstraction we created    HasActivitySubcomponentBuildersinterface (because    Mapof builders doesn’t have to be injected into    Applicationclass):  
  And the final implementation of injection in Activity class:
  It’s pretty similar to our very first implementation, but as mentioned, the most important thing is that we don’t pass    ActivityComponentobject to our Activities anymore.  
  ##Example of use case — instrumentation tests mocking
  Besides loose coupling and fixed circular dependency (Activity <-> Application) which not always is a big issue, especially in smaller projects/teams, let’s consider the real use case where our implementation could be helpful — mocking dependencies in instrumentation testing.
  Currently one of the most known way of mocking dependencies in Android Instrumentation Tests is by using    DaggerMock(Github    project link). While DaggerMock is powerful tool, it’s pretty hard to understand how it works under the hood. Among the others there is some reflection code which isn’t easy to trace.  
    Building Subcomponent directly in Activity, without accessing AppComponent class gives us a way to test every single Activity decoupled from the rest of our app.
    Sounds cool, now take a look at code.
    Application class used in our instrumentation tests:
  Method    putActivityComponentBuilder()gives us a way to replace implementation of ActivityComponentBuilder for given Activity class.  
  Now take a look at our example Espresso Instrumentation Test:
  Step by step:
  
       
  •       We provide Mock of        MainActivityComponent.Builderand all dependencies which have to be mocked (just        Utilsin this case). Our mocked        Builderreturns custom implementation of        MainActivityComponentwhich injects        MainActivityPresenter(with mocked        Utilsobject in it).      
       
  • Then our      MainActivityComponent.Builderreplaces the original Builder injected in      MyApplication(line 28):      app.putActivityComponentBuilder(builder, MainActivity.class);   
  • Finally test — we mock      Utils.getHardcodedText()method. Injection process happens when Activity is created (line 36):      activityRule.launchActivity(new Intent());and at the and we’re just checking the results with Espresso.  
  And that’s all. As you can see almost everything happens in MainActivityUITest class and the code is pretty simple and understandable.
  Source code

  If you would like to test the implementation on your own, source code with working example showing how to create    Activities Multibindingand mock dependencies in Instrumentation Tests is available on Github:    Dagger2Recipes-ActivitiesMultibinding.  
  Thanks for reading!
友荐云推荐




上一篇:Serverless Architecture with Ben Godwin
下一篇:Node v6.9.0 (LTS)
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

d89642995 发表于 2016-10-21 00:51:54
如果跟d89642995讲不清楚,那么就把他搞胡涂吧!  
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表