DI & Dependency Injection

Hilt is used throughout. Key modules in :app/di/:

AppModule

@Module @InstallIn(SingletonComponent::class)
object AppModule {
    @Provides @Singleton
    fun provideAccountManager(...): AccountManager

    @Provides @Singleton
    fun provideAuthManager(...): AuthManager

    @Provides @Singleton
    fun provideSettingsDataStore(...): SettingsDataStore

    @Provides @Singleton
    fun provideProviderFactory(...): (UserProfile) -> EmailProvider  // cached lambda

    @Provides @Singleton
    fun provideEmailRepository(...): EmailRepository

    @Provides @Singleton
    fun provideContactSuggestionProvider(...): ContactSuggestionProvider

    @Provides @Singleton
    fun provideContactPhotoProvider(...): ContactPhotoProvider

    @Provides @Singleton
    fun provideAttachmentCacheManager(...): AttachmentCacheManager
}

DatabaseModule

@Module @InstallIn(SingletonComponent::class)
object DatabaseModule {
    @Provides @Singleton
    fun provideDatabase(@ApplicationContext context: Context): AppDatabase

    @Provides fun provideThreadDao(db: AppDatabase): ThreadDao
    @Provides fun provideEmailDao(db: AppDatabase): EmailDao
    @Provides fun provideScheduledMessageDao(db: AppDatabase): ScheduledMessageDao
    @Provides fun providePendingActionDao(db: AppDatabase): PendingActionDao
}

Cross-module injection

Modules cannot see each other's internal DI. Each module's Hilt module (if any) is installed at the :app level or via the module's own @Module @InstallIn.

For core modules (e.g., :core:pgp), the PgpModule.kt lives in :app and provides the PGP classes as singletons. The module itself (:core:pgp) has no Hilt module — it just provides the classes for :app to wire up.

← UI Layer Build System →