2017-08-12 58 views
0

我的目標:Dagger2子組件混亂

要了解的範圍是如何工作的,以及如何實現一個UserScope,我可以用在多個活動和復位/根據需要創建一個新的。

方法我使用:

  1. 此博客:http://frogermcs.github.io/building-userscope-with-dagger2/
    它顯然解釋說,我想在這裏實現了同樣的事情。

  2. 官方文檔 http://frogermcs.github.io/building-userscope-with-dagger2/

快速簡短的博客

顯然,有UserModuleUserComponent。作者已將UserComponent的創作包裝在UserManager之下,其中有ApplicationScope。所以UserManager在登錄時可用。登錄成功時UserComponent通過UserManager進行初始化。簡單的邏輯。

現在這個已經初始化的@UserScope用於兩個活動中,如圖所示。

什麼,我努力理解

UserComponent看看。

public interface UserComponent { 

    @Subcomponent.Builder 
    interface Builder { 
     Builder sessionModule(UserModule userModule); 

     UserComponent build(); 
    } 

    UserDetailsActivityComponent plus(UserDetailsActivityComponent.UserDetailsActivityModule module); 

    RepositoriesListActivityComponent plus(RepositoriesListActivityComponent.RepositoriesListActivityModule module); 

    LogoutManager logoutManager(); 
} 

具體地說UserDetailsActivityComponentRepositoriesListActivityComponent通過UserComponent創建。與此類似,

@Override 
    protected void onUserComponentSetup(UserComponent userComponent) { 
     userComponent.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this)).inject(this); 
    } 

所以他們第一次打通UserManagerUserComponent預先創建的,然後它調用onUserComponentSetup然後創建相應的組件和注入電流活動。

我失敗了與上述這種模式去理解,我在我們使用plus(InjectionToBeDoneOn i)當我們需要對InjectionToBeDoneOn特定實例的注射的文檔已經閱讀。但爲什麼通過這個組件注入這個Activity?這完成了什麼?用DaggerXYZComponent().Builder().Build().inject(activity)這個活動的onCreate()這個傳統方式做這個沒有意義嗎?

此外,我缺少如何在Android中實現UserScope的體面材料,它具有從登錄到登出但不大於@Singleton範圍的使用期限。

回答

2

我們使用plus(InjectionToBeDoneOn i)當我們需要對InjectionToBeDoneOn

的特定實例

不太注射。 A組分基本上具有三種方法

  1. SomeDependency provideDependency()剛剛創建/提供了一些依賴於子組件,或用於手工檢索(基本上的吸氣劑)
  2. void inject(MyAndroidFrameworkClass object)內噴射的對象,其依賴
  3. SomeSubComponent plus(SubComponentModule module)那創建一個子組件,添加額外的模塊

您正在混合2.和3.這裏。

// user scoped component 
userComponent 
    // create a subcomponent (UserDetailsActivityComponent) 
    .plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this)) 
    // use the UserDetailsActivityComponent that was just created and inject with it 
    .inject(this); 

UserDetailsActivityComponentUserComponent一子,這就是爲什麼userComponent得到擴展.plus(somemodule)創建一個子。如果你的子組件不需要額外的模塊,你也可以使用.plus(),因爲對於Dagger來說重要的是返回類型或者一般的簽名。

  • 如果它返回另一個組件,則它創建一個SubComponent。
  • 如果一個道上參數並返回void或參數的類型,則它是注入方法
  • 如果沒有參數和返回一些類型是是提供方法(1),以暴露一些依賴性

但爲什麼通過這個組件注入這個Activity?這完成了什麼?

如果你要從頭開始創建UserDetailsActivityComponent,它只會看到和了解什麼可以提供本身。如果某個位置有某個@Singleton,則無法訪問它,因爲它不是對象圖的一部分。

子組件擴展了另一個組件,添加到對象圖中。如果你有一個@Singleton A並且你的UserComponentn需要A提供B,用這個子組件將會起作用,沒有它你會得到一個不能提供的錯誤。

匕首並不神奇。它真的只是建立一個有向圖並檢查一切是否正常。如果某些依賴項彼此具有循環依賴關係,或者圖的某些部分無法訪問它所需的依賴項,則會發出抱怨。

您的UserComponent擁有您的用戶數據。爲了簡單起見,我們可以說它擁有UserName。現在UserDetailsActivity可能想要顯示UserName,但它需要一些方法來獲取它。

通過使用@Singleton AppComponent作爲父項,您可以訪問某些Apis,但不能訪問用戶範圍的Apis。您可以將用戶範圍內的對象移動到@Singleton AppComponent中,但是每次用戶更改時都必須重新創建AppComponent(哪種類型的用戶聲明它爲@Singleton,或者您必須找到一些其他方法來更新/用戶更改。

如果你想這樣做,匕首的方式,爲您打造一個UserComponent是增加用戶圖形。子這樣可以訪問它,做他們的用戶的事情。

當用戶更改時,您必須確保銷燬使用UserComponent的任何活動/片段,並且您只需用新用戶重新創建所有內容—。

不會很有意義的傳統方式做的活動OnCreate()DaggerXYZComponent().Builder().Build().inject(activity)

你可以做到這一點,當然。筆者只是把app.getAppcomponent().getUserManager().getUserComponent()或類似的東西放到他們的BaseActivityBaseUserActivity中,這樣你就不必每次都重複相同的代碼行。該方法基本上仍然在onCreate中調用,它只是讓您直接使用這些組件,而不必每次都讀取它們。
很明顯,您可以刪除這些模板方法並在onCreate中內聯所有內容,從而導致代碼重複,從而使維護難以長期進行。

我缺少的UserScope是如何在機器人具有壽命從登錄到註銷,但不大於@SingleTon範圍實現體面材料。

Android沒有幫助,它是你的工作,清理後自己。如果用戶更改,則清除UserComponent及其子組件的所有內容,然後使用新用戶重新創建它。

您必須將具有當前用戶的UserComponent存儲在應用程序類中的某些「真實」單例或具有@Singleton範圍的應用程序組件中的某個「管理器」中。我猜想每種方法都有他們自己的好處。

範圍只是指出匕首,一個對象應該存在於範圍內一次。不管你命名它,或者Scope中有多少個對象。匕首隻需要他們來確保沒有依賴循環。

+0

這很有道理。謝謝。 但'UserModule'沒有'UserDetailsActivityComponent'的'subcomponents'屬性,就像它在Docs中提到的一樣,但UserDetailsActivityComponent'仍然可以作爲UserComponent的子組件? – Ankit

+0

@Ankit我不太明白你在說什麼。你能否詳細說明你的問題? –

+0

這是來自文檔, '要將子組件添加到父組件,請將子組件類添加到父組件安裝的@Module的子組件屬性中。然後,子組件的構建器可以在父組件中請求,即'@Module(subcomponents = RequestComponent.class)' – Ankit