簡體   English   中英

在Android模塊化項目中使用Dagger 2.11

[英]Using Dagger 2.11 with android modular project

我從頭開始研究一個新的Android項目。 了解項目范圍和所需功能后,我提出了一個模塊化架構(基本上將每個功能包裝到功能或android模塊中),如下所示 在此處輸入圖片說明

一切看起來都很完美,直到我想引入匕首粘合所有模塊為止。 問題是我希望每個模塊都有自己的匕首組件/子組件,並且這些模塊是為了提供依賴關系並將它們公開給其他組件或父組件使用的圖形。

Google官方的匕首文檔指出,子組件可以直接訪問父組件依賴關系,反之亦然。 但是,在我的情況下,基本組件需要數據模塊的依賴關系,而后者本身需要網絡模塊的依賴關系。

知道我希望每個android模塊最好有自己的子組件,對此問題有解決方案嗎? 如果沒有,有什么解決辦法嗎?

謝謝。

編輯:這是我的項目結構的樣子

在此處輸入圖片說明

這就是我設置我的匕首圖的方式

在此處輸入圖片說明

我的AppComponent(匕首根)

@Singleton
@Component(modules = {
    AppModule.class,
    ActivityBuilder.class,
    AndroidSupportInjectionModule.class
})
public interface AppComponent {

void inject(CatApp application);

@Component.Builder
interface Builder {
    @BindsInstance
    Builder application(Application application);

    AppComponent build();
}
}

我的應用程序模塊

@Module(subcomponents = DataComponent.class)
public class AppModule {

@Provides
@Singleton
Context provideContext(Application application) {
    return application.getApplicationContext();
}
}

我的DataComponent(位於數據android模塊)

@Subcomponent(modules = DataModule.class)
public interface DataComponent {

@Subcomponent.Builder
interface Builder {
    DataComponent build();
}
}

數據模塊(位於數據android模塊),應提供SystemManager的實現

@Module(subcomponents = NetworkComponent.class)
public class DataModule {

@Provides
@Singleton
ISystemManager provideSystemManager(SystemManager systemManager) {
    return systemManager;
}
}

網絡組件(位於網絡Android模塊中)

@Subcomponent(modules = NetworkModule.class)
public interface NetworkComponent {

@Subcomponent.Builder
interface Builder {
    NetworkComponent build();
}
}

網絡模塊(位於網絡Android模塊上),應提供INetWorkManager實現

@Module
public class NetworkModule {

@Provides
@Singleton
INetworkManager provideNetworkManager(NetworkManager networkManager) {
    return networkManager;
}
}

我在所有構造函數上都使用@Inject批注,因此我的配置已全部完成,但問題是dagger出於某些原因無法編譯這些子組件,並且在編譯時出現此錯誤:

Error:(27, 8) error: [dagger.android.AndroidInjector.inject(T)] com.github.andromedcodes.network.INetworkManager cannot be provided without an @Provides-annotated method.
com.github.andromedcodes.network.INetworkManager is injected at
com.github.andromedcodes.data.SystemManager.<init>(networkManager)
com.github.andromedcodes.data.SystemManager is injected at
com.github.andromedcodes.data.di.DataModule.provideSystemManager(systemManager)
com.github.andromedcodes.domain.managers.ISystemManager is injected at
com.github.andromedcodes.domain.interactors.CheckSystemAvailability.<init>(systemManager)
com.github.andromedcodes.domain.interactors.CheckSystemAvailability is injected at
com.github.andromedcodes.chasseautrsor.views.Splash.SplashPresenter.<init>(checkSystemAvailability)
com.github.andromedcodes.chasseautrsor.views.Splash.SplashPresenter is injected at
com.github.andromedcodes.chasseautrsor.di.SplashModule.bindSplashPresenter(presenter)
com.github.andromedcodes.chasseautrsor.views.Contract.Presenter is injected at
com.github.andromedcodes.mvp.BaseActivity.mPresenter
com.github.andromedcodes.chasseautrsor.views.SplashScreenActivity is injected at
dagger.android.AndroidInjector.inject(arg0)

知道要在Data android Module上提供ISystemManager實現和在Network Android Module上提供INetworkManager時,如何解決此問題?

謝謝。

子組件自動訪問父組件圖中綁定的對象,這很有意義,因為子組件只有一個父組件,因此沒有歧義。 父組件無法自動訪問子組件的圖,因為您可以創建任意數量的子組件實例。 目前尚不清楚您要訪問哪個實例。 通常,除非您需要在對象圖上使用不同的變體(在Guice中使用私有模塊或子注入器來完成),或者除非您想隱藏實現細節(例如內部網絡對象),否則最好安裝模塊全部都在同一個組件中,並跳過子組件策略。

但是,如果您確實想分離圖形或創建多個子組件實例,則也可以在作用域@Provides方法中創建一個子組件實例 這樣,NetworkComponent就有一個帶有私有綁定的單獨圖,但也可以使用您在AppComponent中公開的依賴項,並且還可以確保圖中完全存在NetworkComponent及其相關綁定的一個副本。 您還需要在子組件上放置一個吸氣劑(提供方法或工廠方法),以便可以從外部訪問其某些綁定,就像您在@Component上需要一個吸氣劑或注入器方法一樣有用。

@Subcomponent(modules = NetworkModule.class)
public interface NetworkComponent {

  /** Allow anyone with a NetworkComponent instance to get the INetworkManager. */
  INetworkManager getINetworkManager();

  @Subcomponent.Builder
  interface Builder {
    NetworkComponent build();
  }
}

/**
 * Creates a singleton NetworkComponent. Install this in AppComponent's module,
 * or in your data module if that encapsulates network calls.
 */
@Singleton @Provides NetworkComponent networkComponent(
    NetworkComponent.Builder builder) {
  return builder.build();
}

/** Make the INetworkManager accessible, but not the NetworkManager impl. */
@Provides static provideNetworkManager(NetworkComponent networkComponent) {
  return networkComponent.getINetworkManager();  // add this to NetworkComponent
}

有關更多參考,請參閱Dagger 2文檔中有關子組件的“用於封裝的子組件”部分

使用子組件的另一個原因是彼此封裝了應用程序的不同部分。 例如,如果服務器中的兩個服務(或應用程序中的兩個屏幕)共享一些綁定,例如用於身份驗證和授權的綁定,但是每個綁定都具有實際上彼此無關的其他綁定,則可能有意義每個服務或屏幕的單獨子組件,並將共享綁定放入父組件。

在下面的示例中,@ @Singleton組件中提供了數據庫,但是其所有實現細節都封裝在DatabaseComponent中。 請放心,由於該綁定僅存在於子組件中,因此沒有UI可以訪問DatabaseConnectionPool來調度自己的查詢而無需通過數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM