Hilt のコード生成は、Hilt を使用するすべての Gradle モジュールにアクセスする必要があります。Application
クラスをコンパイルする Gradle モジュールは、すべての Hilt モジュールおよびコンストラクタ インジェクションで注入するクラスを推移的依存関係に含める必要があります。
マルチモジュール プロジェクトが通常の Gradle モジュールで構成されている場合は、Hilt を使用した依存関係の注入の説明に従って Hilt を使用します。しかし、これは機能モジュールを含むアプリには当てはまりません。
機能モジュールでの Hilt
機能モジュールでは、モジュール間での依存の方法が通常とは逆になります。そのため、Hilt では機能モジュール内のアノテーションを処理できません。機能モジュール内で依存関係注入を実行するには、Dagger を使用する必要があります。
機能モジュールでこの問題を解決するには、コンポーネントの依存関係を使用する必要があります。手順は次のとおりです。
app
モジュール内(または、その他の Hilt で処理できるモジュール内)で、機能モジュールに必要な依存関係を指定して@EntryPoint
インターフェースを宣言します。@EntryPoint
インターフェースに依存する Dagger コンポーネントを作成します。- 機能モジュールで通常どおりに Dagger を使用します。
Hilt を使用した依存関係の注入のページで示した例で説明しましょう。login
機能モジュールをプロジェクトに追加するとします。LoginActivity
というアクティビティを使用してログイン機能を実装します。つまり、バインディングはアプリケーション コンポーネントからのみ取得できます。
この機能の場合、authInterceptor
バインディングを含む OkHttpClient
が必要です。
まず、login
モジュールに必要なバインディングを使用して、SingletonComponent
にインストールされた @EntryPoint
インターフェースを作成します。
// LoginModuleDependencies.kt - File in the app module.
@EntryPoint
@InstallIn(SingletonComponent::class)
interface LoginModuleDependencies {
@AuthInterceptorOkHttpClient
fun okHttpClient(): OkHttpClient
}
// LoginModuleDependencies.java - File in the app module.
@EntryPoint
@InstallIn(SingletonComponent.class)
public interface LoginModuleDependencies {
@AuthInterceptorOkHttpClient
OkHttpClient okHttpClient();
}
LoginActivity
でフィールド インジェクションを行うために、@EntryPoint
インターフェースに依存する Dagger コンポーネントを作成します。
// 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
}
}
// 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
のバインディングをクラスの依存関係として使用できます。
// LoginAnalyticsAdapter.kt - File in the login module.
class LoginAnalyticsAdapter @Inject constructor(
@AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
) { ... }
// 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
依存関係を取得します。
// 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)
...
}
}
// 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 を使用するをご覧ください。