マルチモジュール アプリでの Hilt

Hilt のコード生成は、Hilt を使用するすべての Gradle モジュールにアクセスする必要があります。Application クラスをコンパイルする Gradle モジュールは、すべての Hilt モジュールおよびコンストラクタ インジェクションで注入するクラスを推移的依存関係に含める必要があります。

マルチモジュール プロジェクトが通常の Gradle モジュールで構成されている場合は、Hilt を使用した依存関係の注入の説明に従って Hilt を使用します。しかし、これは機能モジュールを含むアプリには当てはまりません。

機能モジュールでの Hilt

機能モジュールでは、モジュール間での依存の方法が通常とは逆になります。そのため、Hilt では機能モジュール内のアノテーションを処理できません。機能モジュール内で依存関係注入を実行するには、Dagger を使用する必要があります。

機能モジュールでこの問題を解決するには、コンポーネントの依存関係を使用する必要があります。手順は次のとおりです。

  1. app モジュール内(または、その他の Hilt で処理できるモジュール内)で、機能モジュールに必要な依存関係を指定して @EntryPoint インターフェースを宣言します。
  2. @EntryPoint インターフェースに依存する Dagger コンポーネントを作成します。
  3. 機能モジュールで通常どおりに Dagger を使用します。

Hilt を使用した依存関係の注入のページで示した例で説明しましょう。login 機能モジュールをプロジェクトに追加するとします。LoginActivity というアクティビティを使用してログイン機能を実装します。つまり、バインディングはアプリケーション コンポーネントからのみ取得できます。

この機能の場合、authInterceptor バインディングを含む OkHttpClient が必要です。

まず、login モジュールに必要なバインディングを使用して、SingletonComponent にインストールされた @EntryPoint インターフェースを作成します。

Kotlin

// LoginModuleDependencies.kt - File in the app module.

@EntryPoint
@InstallIn(SingletonComponent::class)
interface LoginModuleDependencies {

  @AuthInterceptorOkHttpClient
  fun okHttpClient(): OkHttpClient
}

Java

// LoginModuleDependencies.java - File in the app module.

@EntryPoint
@InstallIn(SingletonComponent.class)
public interface LoginModuleDependencies {

  @AuthInterceptorOkHttpClient
  OkHttpClient okHttpClient();
}

LoginActivity でフィールド インジェクションを行うために、@EntryPoint インターフェースに依存する Dagger コンポーネントを作成します。

Kotlin

// LoginComponent.kt - File in the login module.

@Component(dependencies = [LoginModuleDependencies::class])
interface LoginComponent {

  fun inject(activity: LoginActivity)

  @Component.Builder
  interface Builder {
    fun context(@BindsInstance context: Context): Builder
    fun appDependencies(loginModuleDependencies: LoginModuleDependencies): Builder
    fun build(): LoginComponent
  }
}

Java

// LoginComponent.java - File in the login module.

@Component(dependencies = LoginModuleDependencies.class)
public interface LoginComponent {

  void inject(LoginActivity loginActivity);

  @Component.Builder
  interface Builder {
    Builder context(@BindsInstance Context context);
    Builder appDependencies(LoginModuleDependencies loginModuleDependencies);
    LoginComponent build();
  }
}

以上の手順を完了したら、機能モジュールで通常どおりに Dagger を使用します。たとえば、SingletonComponent のバインディングをクラスの依存関係として使用できます。

Kotlin

// LoginAnalyticsAdapter.kt - File in the login module.

class LoginAnalyticsAdapter @Inject constructor(
  @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
) { ... }

Java

// LoginAnalyticsAdapter.java - File in the login module.

public class LoginAnalyticsAdapter {

  private final OkHttpClient okHttpClient;

  @Inject
  LoginAnalyticsAdapter(
    @AuthInterceptorOkHttpClient OkHttpClient okHttpClient
  ) {
    this.okHttpClient = okHttpClient;
  }
  ...
}

フィールド インジェクションを実行するために、applicationContext を使用して Dagger コンポーネントのインスタンスを作成し、SingletonComponent 依存関係を取得します。

Kotlin

// LoginActivity.kt - File in the login module.

class LoginActivity : AppCompatActivity() {

  @Inject
  lateinit var loginAnalyticsAdapter: LoginAnalyticsAdapter

  override fun onCreate(savedInstanceState: Bundle?) {
    DaggerLoginComponent.builder()
        .context(this)
        .appDependencies(
          EntryPointAccessors.fromApplication(
            applicationContext,
            LoginModuleDependencies::class.java
          )
        )
        .build()
        .inject(this)

    super.onCreate(savedInstanceState)
    ...
  }
}

Java

// LoginActivity.java - File in the login module.

public class LoginActivity extends AppCompatActivity {

  @Inject
  LoginAnalyticsAdapter loginAnalyticsAdapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    DaggerLoginComponent.builder()
        .context(this)
        .appDependencies(
          EntryPointAccessors.fromApplication(
            getApplicationContext(),
            LoginModuleDependencies.class
          )
        )
        .build()
        .inject(this);

    super.onCreate(savedInstanceState);
    ...
  }
}

機能モジュールのモジュール依存関係について詳しくは、コンポーネント依存関係と機能モジュールをご覧ください。

Android での Dagger の詳細については、Android アプリで Dagger を使用するをご覧ください。