Hilt ในแอปหลายโมดูล

การสร้างโค้ด Hilt ต้องมีสิทธิ์เข้าถึงโมดูล Gradle ทั้งหมดที่ใช้ Hilt โมดูล Gradle ที่คอมไพล์ ชั้นเรียน Application ต้องมี Hilt ทั้งหมด โมดูลและคลาสที่แทรกโดยตัวสร้างในทรัพยากร Dependency แบบทรานซิทีฟ

หากโปรเจ็กต์หลายโมดูลของคุณประกอบด้วยโมดูล Gradle ปกติ คุณจะดำเนินการต่อไปนี้ได้ ใช้ Hilt ตามที่อธิบายไว้ใน Dependency Injection กับ Hilt อย่างไรก็ตาม นี่ไม่ใช่ แอปที่ประกอบด้วยฟีเจอร์ โมดูล

ฮิลต์ในโมดูลฟีเจอร์

ในโมดูลฟีเจอร์ วิธีที่โมดูลมักพึ่งพากันนั้นมีการกลับกัน ดังนั้น Hilt จึงไม่สามารถประมวลผลคำอธิบายประกอบในโมดูลฟีเจอร์ คุณต้อง ใช้ Dagger เพื่อแสดง Dependency Injection ในโมดูลฟีเจอร์

คุณต้องใช้ทรัพยากร Dependency ของคอมโพเนนต์เพื่อแก้ปัญหานี้กับโมดูลฟีเจอร์ ติดตาม ขั้นตอนเหล่านี้:

  1. ประกาศ อินเทอร์เฟซ @EntryPoint ในโมดูล app (หรือในโมดูลอื่นๆ ที่ Hilt ประมวลผลได้) กับทรัพยากร Dependency ที่โมดูลฟีเจอร์ต้องการ
  2. สร้างคอมโพเนนต์ Dagger ที่ขึ้นอยู่กับอินเทอร์เฟซ @EntryPoint
  3. ใช้ Dagger ตามปกติในโมดูลฟีเจอร์

ลองพิจารณาตัวอย่างจาก Dependency Injection ด้วย Hilt สมมติว่าคุณเพิ่ม login โมดูลฟีเจอร์ไปยังโปรเจ็กต์ของคุณ คุณใช้ฟีเจอร์การเข้าสู่ระบบ กับกิจกรรมชื่อ LoginActivity ซึ่งหมายความว่าคุณสามารถได้รับการเชื่อมโยง จากคอมโพเนนต์ของแอปพลิเคชันเท่านั้น

สำหรับฟีเจอร์นี้ คุณต้องมี OkHttpClient ที่มีการเชื่อมโยง authInterceptor

ขั้นแรก ให้สร้างอินเทอร์เฟซ @EntryPoint ที่ติดตั้งใน SingletonComponent กับการเชื่อมโยงที่โมดูล login ต้องการ

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 ให้สร้าง Dagger คอมโพเนนต์ที่ขึ้นอยู่กับอินเทอร์เฟซ @EntryPoint

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;
  }
  ...
}

สร้างอินสแตนซ์ของคอมโพเนนต์ Dagger เพื่อทำการแทรกช่อง ใช้ applicationContext เพื่อรับการอ้างอิง 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);
    ...
  }
}

หากต้องการทราบบริบทเพิ่มเติมเกี่ยวกับทรัพยากร Dependency ของโมดูลในโมดูลฟีเจอร์ โปรดดู ทรัพยากร Dependency ของคอมโพเนนต์พร้อมฟีเจอร์ โมดูล

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Dagger บน Android โปรดดูการใช้ Dagger ใน Android แอป