Dagger / Hilt: co to je, DI a použití

Autor: IT Sectr Publikováno: 2026-05-03 Doba čtení: 9 min

Dagger — je framework pro vkládání závislostí pro Javu a Kotlin, který generuje DI kód v době kompilace prostřednictvím zpracování anotací. Hilt — je nadstavba nad Daggerem pro Android, která zjednodušuje konfiguraci komponent a životního cyklu. Podle údajů Google, 2025 je Hilt používán ve více než 70% Android aplikací z Google Play Top-100, podporuje Activity, Fragment, ViewModel a Service prostřednictvím předdefinovaných komponent. Oba frameworky zajišťují kontrolu grafu závislostí v době kompilace, čímž eliminují chyby vkládání za běhu.

Hlavní body

  • Dagger — DI framework pro čas kompilace s generováním kódu přes anotace @Module, @Provides, @Component
  • Hilt — nadstavba pro Android zjednodušující Dagger přes @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel
  • Component — graf závislostí propojující Module s cíli Inject přes proxy metody
  • Scope — @Singleton, @ViewModelScoped, @ActivityScoped spravují životnost vkládaných objektů
  • Hilt podporuje multimodulární projekty přes @InstallIn pro izolované grafy závislostí

Co je Dagger / Hilt?

Dagger — je framework pro vkládání závislostí s generováním kódu v době kompilace (compile-time DI). Vyvinutý ve Square a později předaný Google, Dagger používá procesor anotací Java APT k analýze grafu závislostí a generování továrních tříd. Na rozdíl od runtime-DI (Guice, Koin) Dagger nepoužívá reflexi — veškerý kód je vytvořen při kompilaci, což zajišťuje maximální výkon za běhu a odhalování chyb ve fázi sestavení.

Hilt — je knihovna od Google, postavená na Daggeru a optimalizovaná pro Android. Hilt poskytuje předdefinované komponenty odpovídající životnímu cyklu Android komponent: @SingletonComponent pro Application, @ActivityComponent pro Activity, @FragmentComponent pro Fragment, @ViewModelComponent pro ViewModel. To eliminuje rutinní konfiguraci Component a Module, která je vyžadována v čistém Daggeru. Hilt také automaticky generuje graf závislostí pro každou Android komponentu prostřednictvím @AndroidEntryPoint.

Podle Google I/O 2024 je Hilt doporučeným řešením DI pro Android aplikace napsané v Kotlinu. Knihovny Jetpack (Navigation, Room, WorkManager) mají vestavěnou integraci s Hiltem přes @HiltViewModel a @HiltWorker. V projektech, které nepoužívají Android (čisté Java/Kotlin knihovny, serverové aplikace), se používá čistý Dagger bez nadstavby Hilt.

Problém ručního vkládání závislostí

Bez DI frameworku vývojář vytváří objekty ručně pomocí konstruktorů nebo továren, přičemž předává závislosti v řetězci. Každý nový požadavek — změna signatury všech konstruktorů v řetězci. Dagger tento proces automatizuje: stačí deklarovat, jaký typ je požadován (@Inject constructor), a Dagger vytvoří graf závislostí, vyřeší všechny vnořené typy. Při změně závislostí Dagger automaticky aktualizuje generovaný kód — v řetězci nelze udělat chybu.

Principy vkládání závislostí

Vkládání závislostí (Dependency Injection) — je vzor, při kterém objekt přijímá své závislosti z venku, místo aby je sám vytvářel. DI implementuje princip inverze řízení (IoC): třída není odpovědná za vytváření svých závislostí, ale deklaruje je prostřednictvím konstruktoru, metody nebo pole. Vkládání přes konstruktor (constructor injection) je považováno za nejpreferovanější, protože zaručuje, že objekt je vytvořen v platném stavu.

Typ vkládáníSyntaxe DaggeruKdy použít
Constructor injection@Inject constructorHlavní způsob — pro všechny vlastní třídy
Field injection@Inject lateinit varPouze pro Android komponenty (Activity, Fragment)
Method injection@Inject fun bind()Pro post-construct inicializaci

Výhody compile-time DI

Hlavní výhody DI zahrnují testovatelnost (závislosti lze nahradit mock objekty), volnou provázanost (třídy závisí na rozhraních, ne na implementacích) a explicitní správu životního cyklu objektů pomocí scope. Dagger automaticky zaručuje, že objekt je vytvořen jednou v rámci svého scopu a zničen při opuštění scopu.

Architektura Daggeru: Component, Module, Provides

Component — centrální prvek grafu závislostí Daggeru. Je to rozhraní anotované @Component, které popisuje most mezi Modulem a cíli vkládání. Dagger generuje implementaci Component (např. DaggerAppComponent) v době kompilace. Component určuje, které typy jsou k dispozici pro vkládání, prostřednictvím abstraktních metod vracejících požadované typy nebo metod inject přijímajících objekt pro field injection.

kotlin
// Modul: poskytuje závislosti, které Dagger nemůže vytvořit sám
@Module
class NetworkModule {
    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .build()
    }

    @Provides
    @Singleton
    fun provideApiService(client: OkHttpClient): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}

// Komponenta: propojuje Module a cíle vkládání
@Component(modules = [NetworkModule::class])
interface AppComponent {
    fun inject(activity: MainActivity)
    fun getApiService(): ApiService
}

@Module — je třída obsahující metody s @Provides, které vracejí instance závislostí. Module se používá pro typy, které Dagger nemůže vytvořit automaticky: knihovny třetích stran (OkHttp, Retrofit), objekty s parametry konstruktoru, rozhraní s výběrem implementace. @Binds — alternativa k @Provides pro případy, kdy metoda vrací rozhraní a přijímá jedinou implementaci: Dagger generuje přímý přetypování bez volání metody.

@Scope určuje životnost objektu v grafu závislostí. @Singleton — objekt je vytvořen jednou pro celou aplikaci. @ActivityScoped — objekt žije, dokud žije Activity. @FragmentScoped — dokud žije Fragment. Bez scopu Dagger vytváří novou instanci při každém vkládání. @Reusable — scope pro objekty, které nemusí být singly, ale jejich vytvoření je nákladné — Dagger může instanci ukládat do mezipaměti, ale nezaručuje to.

Hilt pro Android: @HiltAndroidApp a @AndroidEntryPoint

Hilt zjednodušuje konfiguraci Daggeru pro Android díky předdefinovaným komponentám a automatickému generování základního grafu. Anotace @HiltAndroidApp na třídě Application spouští generování Hilt komponenty. Bez této anotace Hilt nefunguje — je povinná pro každou Android aplikaci používající Hilt. @HiltAndroidApp vytváří rodičovskou komponentu SingletonComponent, od které dědí všechny ostatní komponenty aplikace.

kotlin
@HiltAndroidApp
class MyApplication : Application()

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject lateinit var apiService: ApiService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // apiService byl již vložen před voláním onCreate
    }
}

@Module
@InstallIn(SingletonComponent::class)
class AppModule {
    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext ctx: Context): AppDatabase {
        return Room.databaseBuilder(ctx, AppDatabase::class.java, "app.db").build()
    }
}

@AndroidEntryPoint — anotace pro Activity, Fragment, Service, BroadcastReceiver a View. Generuje Hilt komponentu pro každý typ: @AndroidEntryPoint na Activity vytváří ActivityComponent, který dědí z SingletonComponent. Dceřiná komponenta automaticky přijímá všechny závislosti rodiče. Field injection s @Inject lateinit var je k dispozici pouze ve třídách anotovaných @AndroidEntryPoint — v běžných třídách se používá constructor injection.

@InstallIn určuje, do které Hilt komponenty je modul nainstalován. NetworkModule s @InstallIn(SingletonComponent::class) je k dispozici v celé aplikaci. Module s @InstallIn(ActivityComponent::class) — pouze v Activity. To izoluje grafy závislostí: moduly specifické pro Activity nejsou viditelné ve Fragment a ViewModel, čímž se zabraňuje náhodnému použití nepovolených závislostí. @ApplicationContext — vestavěný kvalifikátor Hiltu pro získání kontextu aplikace.

Qualifier: @Named a vlastní kvalifikátory

Když je třeba vložit dvě různé implementace stejného rozhraní, používají se kvalifikátory. Hilt podporuje @Named pro textové identifikátory a vlastní anotace s @Qualifier. Například @Named("baseUrl") a @Named("imageBaseUrl") pro různé textové konfigurace. Vlastní kvalifikátory jsou preferovány před @Named kvůli kontrole v době kompilace — nesprávný textový název nebude odhalen až do běhu.

Hilt ViewModel: @HiltViewModel a @Inject constructor

@HiltViewModel — anotace nahrazující ruční továrnu ViewModelProvider.Factory. Třída anotovaná @HiltViewModel s @Inject constructor automaticky přijímá všechny závislosti přes Dagger. Hilt generuje ViewModelFactory používanou Jetpack ViewModelProvider. Bez Hiltu by vývojář musel psát továrnu ručně a předávat každý parametr z Activity nebo fragmentu.

kotlin
@HiltViewModel
class MainViewModel
    @Inject constructor(
        private val apiService: ApiService,
        private val database: AppDatabase
    ) : ViewModel() {

    private val _users = MutableStateFlow<List<User>>(emptyList())
    val users: StateFlow<List<User>> = _users.asStateFlow()

    fun loadUsers() {
        viewModelScope.launch {
            _users.value = apiService.getUsers()
        }
    }
}

// V Activity — Hilt automaticky vytváří ViewModel
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by viewModels()
}

ViewModelScoped — scope Hiltu pro závislosti, které žijí, dokud žije ViewModel. Pokud dva ViewModel stejného typu vkládají stejnou závislost @ViewModelScoped, každý dostane svou vlastní instanci. To odlišuje @ViewModelScoped od @ActivityScoped, kde jedna Activity dostává jednu instanci pro všechny fragmenty. Pro závislosti specifické pro ViewModel (např. SavedStateHandle) použijte @HiltViewModel s @Inject constructor(savedStateHandle: SavedStateHandle).

Hilt podporuje assisted injection prostřednictvím knihovny Hilt Extensions. Assisted injection umožňuje předávat parametry konstruktoru během vkládání, když je část závislostí známa pouze za běhu (např. ID uživatele z intentu). Pro assisted injection se používá @AssistedInject v kombinaci s parametry @Assisted. Hilt generuje AssistedFactory, kterou lze vložit standardním způsobem.

Dagger vs Hilt: srovnání a migrace

Čistý Dagger vyžaduje ruční vytvoření Component, definování scopů a konfiguraci vkládání v každé Android komponentě. Vývojář vytváří AppComponent, ActivityComponent, FragmentComponent a spravuje jejich vztahy prostřednictvím @Subcomponent. Tento přístup poskytuje maximální kontrolu, ale vyžaduje značné množství boilerplate kódu. Dagger se používá ve velkých projektech, kde je vyžadována vlastní DI architektura, nebo v ne-Android Java/Kotlin projektech.

Hilt automatizuje boilerplate: jeden @HiltAndroidApp, jeden @AndroidEntryPoint pro každou komponentu, předdefinované scopy. Hilt je doporučován Googlem pro všechny nové Android projekty. Migrace z Daggeru na Hilt zahrnuje nahrazení Component za @InstallIn, nahrazení @Subcomponent za předdefinované Hilt komponenty a nahrazení ručního ViewModelProvider.Factory za @HiltViewModel. Většina tříd @Module se přenáší s přidáním @InstallIn beze změny metod @Provides.

VlastnostDaggerHilt
KonfiguraceRuční: Component, Subcomponent, BuilderAutomatická: @HiltAndroidApp, @AndroidEntryPoint
Android komponentyŽádné předdefinované12+ vestavěných komponent
ViewModelRuční továrna@HiltViewModel + @Inject constructor
MultimodulPřes @Component(dependencies)Přes @InstallIn + agregaci
SložitostVysoká — vyžaduje zkušenostiNízká — intuitivní
FlexibilitaMaximálníStandardní (pokrývá 95% scénářů)

Omezení Hiltu: knihovna podporuje pouze Android (není vhodná pro čistě serverové Java projekty), vynucuje určitou strukturu komponent (obtížně přepisovatelnou) a přidává závislost na android.hilt:hilt-navigation-compose pro Jetpack Compose projekty. Pro Compose aplikace Hilt poskytuje @HiltViewModel dostupný v Composable přes hiltViewModel() — bez ručního poskytování ViewModel z Activity.

Často kladené otázky

Jaký je rozdíl mezi Daggerem a Hiltem?

Dagger — základní compile-time DI framework s ruční konfigurací Component a Module. Hilt — nadstavba pro Android automatizující vytváření komponent a integraci s životním cyklem Activity, Fragment, ViewModel, Service a BroadcastReceiver.

K čemu slouží @HiltAndroidApp?

@HiltAndroidApp spouští generování Hilt komponenty pro Application. Bez této anotace Hilt nemůže vytvořit základní komponentu SingletonComponent, od které dědí všechny ActivityComponent, FragmentComponent a ViewModelComponent. Anotace je povinná pro každý Hilt projekt.

Jak Hilt pracuje s Jetpack Navigation?

Hilt Navigation poskytuje @HiltViewModel pro ViewModel v NavBackStackEntry a hiltNavGraphViewModels() pro scopování ViewModel v rámci navigačního grafu. Knihovna android.hilt:hilt-navigation-fragment automaticky vytváří ViewModel pro každý NavBackStackEntry.

Jak vložit Context v Hiltu?

Použijte @ApplicationContext pro kontext aplikace nebo @ActivityContext pro kontext Activity. Hilt poskytuje tyto kvalifikátory vestavěné v knihovně android.hilt:hilt-android. @ActivityContext je k dispozici pouze v modulech nainstalovaných v ActivityComponent.

Co je @Binds a kdy se používá?

@Binds — účinná alternativa k @Provides, když metoda přijímá přesně jeden parametr a vrací jeho typ jako rozhraní. @Binds generuje přímé přetypování bez volání metody, což snižuje množství generovaného kódu a zvyšuje výkon při vkládání.

Shrnutí

  • Dagger — DI framework pro čas kompilace s anotacemi @Module, @Provides, @Component a generováním kódu přes APT
  • Hilt — Android nadstavba nad Daggerem s @HiltAndroidApp, @AndroidEntryPoint, @InstallIn a předdefinovanými komponentami
  • Component spravuje graf závislostí, Module poskytuje třídy třetích stran, Provides — továrny objektů
  • Scope (@Singleton, @ViewModelScoped, @ActivityScoped) určuje životnost objektu v grafu Daggeru
  • @HiltViewModel automatizuje vytváření ViewModel, eliminuje ruční továrny ViewModelProvider.Factory
  • @InstallIn izoluje moduly podle komponent, zabraňuje úniku závislostí mezi vrstvami aplikace
  • Hilt je doporučován Googlem pro všechny nové Android projekty, Dagger — pro ne-Android a vlastní DI architektury

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také