Dagger Java और Kotlin के लिए एक डिपेंडेंसी इंजेक्शन फ्रेमवर्क है जो एनोटेशन प्रोसेसिंग के माध्यम से कंपाइल समय पर DI कोड जनरेट करता है। Hilt Android के लिए Dagger के ऊपर एक आवरण है जो घटक सेटअप और जीवनचक्र प्रबंधन को सरल बनाता है। Google, 2025 के अनुसार, Google Play Top-100 से 70% से अधिक Android ऐप्स में Hilt का उपयोग किया जाता है, जो पूर्वनिर्धारित घटकों के माध्यम से Activity, Fragment, ViewModel और Service का समर्थन करता है। दोनों फ्रेमवर्क कंपाइल-टाइम डिपेंडेंसी ग्राफ सत्यापन प्रदान करते हैं, रनटाइम इंजेक्शन त्रुटियों को समाप्त करते हैं।
मुख्य बातें
Dagger एक डिपेंडेंसी इंजेक्शन फ्रेमवर्क है जो कंपाइल-टाइम कोड जनरेशन के साथ आता है। मूल रूप से Square में विकसित और बाद में Google को हस्तांतरित, Dagger डिपेंडेंसी ग्राफ का विश्लेषण करने और फैक्ट्री क्लासेस जनरेट करने के लिए Java APT एनोटेशन प्रोसेसर का उपयोग करता है। रनटाइम-DI (Guice, Koin) के विपरीत, Dagger रिफ्लेक्शन का उपयोग नहीं करता — सारा कोड कंपाइल समय पर बनाया जाता है, जो रनटाइम में अधिकतम प्रदर्शन और बिल्ड समय पर त्रुटि का पता लगाना सुनिश्चित करता है।
Hilt एक Google लाइब्रेरी है जो Dagger के ऊपर बनाई गई है और Android के लिए अनुकूलित है। Hilt Android घटक जीवनचक्र के अनुरूप पूर्वनिर्धारित घटक प्रदान करता है: Application के लिए @SingletonComponent, Activity के लिए @ActivityComponent, Fragment के लिए @FragmentComponent, ViewModel के लिए @ViewModelComponent। यह शुद्ध Dagger में आवश्यक नियमित Component और Module कॉन्फ़िगरेशन को समाप्त करता है। Hilt @AndroidEntryPoint के माध्यम से प्रत्येक Android घटक के लिए स्वचालित रूप से डिपेंडेंसी ग्राफ भी जनरेट करता है।
Google I/O 2024 के अनुसार, Kotlin में लिखे Android ऐप्स में DI के लिए Hilt अनुशंसित समाधान है। Jetpack लाइब्रेरीज़ (Navigation, Room, WorkManager) में @HiltViewModel और @HiltWorker के माध्यम से Hilt के साथ अंतर्निहित एकीकरण है। उन प्रोजेक्ट्स में जो Android का उपयोग नहीं करते (शुद्ध Java/Kotlin लाइब्रेरीज़, सर्वर ऐप्लिकेशन), Hilt आवरण के बिना शुद्ध Dagger का उपयोग किया जाता है।
DI फ्रेमवर्क के बिना, डेवलपर कंस्ट्रक्टर या फैक्ट्री के माध्यम से मैन्युअल रूप से ऑब्जेक्ट बनाता है, श्रृंखला के साथ डिपेंडेंसी पास करता है। प्रत्येक नई आवश्यकता का मतलब श्रृंखला में सभी कंस्ट्रक्टर के सिग्नेचर बदलना है। Dagger इस प्रक्रिया को स्वचालित करता है: आप बस घोषित करते हैं कि किस प्रकार की आवश्यकता है (@Inject constructor), और Dagger सभी नेस्टेड प्रकारों को हल करते हुए डिपेंडेंसी ग्राफ बनाता है। जब डिपेंडेंसी बदलती हैं, Dagger स्वचालित रूप से जनरेटेड कोड अपडेट करता है — श्रृंखला में गलती करना असंभव है।
डिपेंडेंसी इंजेक्शन एक पैटर्न है जिसमें कोई ऑब्जेक्ट अपनी डिपेंडेंसी बाहर से प्राप्त करता है, न कि उन्हें स्वयं बनाकर। DI नियंत्रण के उलट (IoC) सिद्धांत को लागू करता है: एक क्लास अपनी डिपेंडेंसी बनाने के लिए जिम्मेदार नहीं है, बल्कि उन्हें कंस्ट्रक्टर, विधि या फील्ड के माध्यम से घोषित करता है। कंस्ट्रक्टर इंजेक्शन को सबसे अधिक पसंद किया जाता है क्योंकि यह सुनिश्चित करता है कि ऑब्जेक्ट मान्य स्थिति में बनाया गया है।
| इंजेक्शन का प्रकार | Dagger सिंटैक्स | कब उपयोग करें |
|---|---|---|
| Constructor injection | @Inject constructor | मुख्य विधि — सभी कस्टम क्लासेस के लिए |
| Field injection | @Inject lateinit var | केवल Android घटकों के लिए (Activity, Fragment) |
| Method injection | @Inject fun bind() | पोस्ट-कंस्ट्रक्ट इनिशियलाइज़ेशन के लिए |
DI के मुख्य लाभों में परीक्षण क्षमता (डिपेंडेंसी को mock ऑब्जेक्ट से बदला जा सकता है), ढीला युग्मन (क्लासेस इंटरफेस पर निर्भर करती हैं, कार्यान्वयन पर नहीं), और स्कोप के माध्यम से ऑब्जेक्ट के जीवनचक्र का स्पष्ट प्रबंधन शामिल है। Dagger स्वचालित रूप से गारंटी देता है कि कोई ऑब्जेक्ट अपने स्कोप के भीतर एक बार बनाया जाता है और स्कोप से बाहर निकलने पर नष्ट कर दिया जाता है।
Component Dagger डिपेंडेंसी ग्राफ का केंद्रीय तत्व है। यह @Component से एनोटेटेड एक इंटरफ़ेस है जो Module और इंजेक्शन लक्ष्यों के बीच पुल का वर्णन करता है। Dagger कंपाइल समय पर Component कार्यान्वयन (जैसे DaggerAppComponent) जनरेट करता है। Component यह निर्धारित करता है कि आवश्यक प्रकार लौटाने वाले अमूर्त विधियों या फील्ड इंजेक्शन के लिए ऑब्जेक्ट स्वीकार करने वाले inject विधियों के माध्यम से इंजेक्शन के लिए कौन से प्रकार उपलब्ध हैं।
// Module: वे डिपेंडेंसी प्रदान करता है जिन्हें Dagger स्वयं नहीं बना सकता
@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)
}
}
// Component: Module और Injection लक्ष्यों को जोड़ता है
@Component(modules = [NetworkModule::class])
interface AppComponent {
fun inject(activity: MainActivity)
fun getApiService(): ApiService
}
@Module एक क्लास है जिसमें @Provides के साथ विधियाँ होती हैं जो डिपेंडेंसी के इंस्टेंस लौटाती हैं। Module का उपयोग उन प्रकारों के लिए किया जाता है जिन्हें Dagger स्वचालित रूप से नहीं बना सकता: तृतीय-पक्ष लाइब्रेरीज़ (OkHttp, Retrofit), कंस्ट्रक्टर पैरामीटर वाली वस्तुएँ, कार्यान्वयन चयन वाले इंटरफ़ेस। @Binds @Provides का एक विकल्प है उन मामलों के लिए जब कोई विधि इंटरफ़ेस लौटाती है और एक एकल कार्यान्वयन स्वीकार करती है: Dagger विधि को कॉल किए बिना प्रत्यक्ष कास्ट जनरेट करता है।
@Scope डिपेंडेंसी ग्राफ में ऑब्जेक्ट के जीवनकाल को परिभाषित करता है। @Singleton — ऑब्जेक्ट पूरे एप्लिकेशन के लिए एक बार बनाया जाता है। @ActivityScoped — ऑब्जेक्ट तब तक जीवित रहता है जब तक Activity जीवित है। @FragmentScoped — जब तक Fragment जीवित है। स्कोप के बिना, Dagger प्रत्येक इंजेक्शन पर एक नया इंस्टेंस बनाता है। @Reusable — उन ऑब्जेक्ट के लिए स्कोप जो सिंगलटन होने के लिए आवश्यक नहीं हैं लेकिन जिनका निर्माण महँगा है — Dagger इंस्टेंस को कैश कर सकता है लेकिन इसकी गारंटी नहीं देता।
Hilt पूर्वनिर्धारित घटकों और स्वचालित आधार ग्राफ जनरेशन के माध्यम से Android के लिए Dagger कॉन्फ़िगरेशन को सरल बनाता है। Application क्लास पर @HiltAndroidApp एनोटेशन Hilt घटक जनरेशन को ट्रिगर करता है। इस एनोटेशन के बिना, Hilt काम नहीं करता — यह Hilt का उपयोग करने वाले किसी भी Android एप्लिकेशन के लिए अनिवार्य है। @HiltAndroidApp मूल SingletonComponent बनाता है, जिससे एप्लिकेशन के सभी अन्य घटक प्राप्त होते हैं।
@HiltAndroidApp
class MyApplication : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var apiService: ApiService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// apiService 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 Activity, Fragment, Service, BroadcastReceiver और View के लिए एक एनोटेशन है। यह प्रत्येक प्रकार के लिए Hilt घटक जनरेट करता है: Activity पर @AndroidEntryPoint एक ActivityComponent बनाता है जो SingletonComponent से प्राप्त होता है। चाइल्ड घटक स्वचालित रूप से पैरेंट की सभी डिपेंडेंसी प्राप्त करता है। @Inject lateinit var के साथ Field injection केवल @AndroidEntryPoint से एनोटेटेड क्लासेस में उपलब्ध है — सामान्य क्लासेस में कंस्ट्रक्टर इंजेक्शन का उपयोग किया जाता है।
@InstallIn निर्दिष्ट करता है कि मॉड्यूल किस Hilt घटक में स्थापित किया गया है। @InstallIn(SingletonComponent::class) के साथ NetworkModule पूरे एप्लिकेशन में उपलब्ध है। @InstallIn(ActivityComponent::class) के साथ Module केवल Activity में उपलब्ध है। यह डिपेंडेंसी ग्राफ़ को अलग करता है: Activity-विशिष्ट मॉड्यूल Fragment और ViewModel में दिखाई नहीं देते, अमान्य डिपेंडेंसी के आकस्मिक उपयोग को रोकते हैं। @ApplicationContext एप्लिकेशन Context प्राप्त करने के लिए Hilt का अंतर्निहित क्वालिफायर है।
जब एक ही इंटरफ़ेस के दो अलग-अलग कार्यान्वयनों को इंजेक्ट करने की आवश्यकता होती है, तो क्वालिफायर का उपयोग किया जाता है। Hilt स्ट्रिंग पहचानकर्ताओं के लिए @Named और @Qualifier के साथ कस्टम एनोटेशन का समर्थन करता है। उदाहरण के लिए, विभिन्न स्ट्रिंग कॉन्फ़िगरेशन के लिए @Named("baseUrl") और @Named("imageBaseUrl")। कस्टम क्वालिफायर कंपाइल-टाइम जाँच के कारण @Named से बेहतर होते हैं — गलत स्ट्रिंग नाम रनटाइम तक पता नहीं चलेगा।
@HiltViewModel एक एनोटेशन है जो मैन्युअल ViewModelProvider.Factory को बदलता है। @HiltViewModel से एनोटेटेड और @Inject constructor वाली क्लास स्वचालित रूप से Dagger के माध्यम से सभी डिपेंडेंसी प्राप्त करती है। Hilt Jetpack ViewModelProvider द्वारा उपयोग की जाने वाली ViewModelFactory जनरेट करता है। Hilt के बिना, डेवलपर को Activity या फ्रैगमेंट से प्रत्येक पैरामीटर पास करते हुए, मैन्युअल रूप से फैक्ट्री लिखनी होती है।
@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()
}
}
}
// Activity में — Hilt स्वचालित रूप से ViewModel बनाता है
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
}
ViewModelScoped डिपेंडेंसी के लिए Hilt का स्कोप है जो तब तक जीवित रहता है जब तक ViewModel जीवित है। यदि एक ही प्रकार के दो ViewModel एक ही @ViewModelScoped डिपेंडेंसी को इंजेक्ट करते हैं, तो प्रत्येक को अपना स्वयं का इंस्टेंस मिलता है। यह @ViewModelScoped को @ActivityScoped से अलग करता है, जहाँ एक Activity को सभी फ्रैगमेंट के लिए एक इंस्टेंस मिलता है। ViewModel-विशिष्ट डिपेंडेंसी (जैसे SavedStateHandle) के लिए, @HiltViewModel का उपयोग @Inject constructor(savedStateHandle: SavedStateHandle) के साथ किया जाता है।
Hilt Hilt Extensions लाइब्रेरी के माध्यम से assisted injection का समर्थन करता है। Assisted injection इंजेक्शन के समय कंस्ट्रक्टर में पैरामीटर पास करने की अनुमति देता है जब कुछ डिपेंडेंसी केवल रनटाइम पर ज्ञात होती हैं (उदाहरण के लिए, इंटेंट से उपयोगकर्ता ID)। Assisted injection के लिए @AssistedInject का उपयोग @Assisted पैरामीटर के संयोजन में किया जाता है। Hilt एक AssistedFactory जनरेट करता है जिसे मानक तरीके से इंजेक्ट किया जा सकता है।
शुद्ध Dagger के लिए Component का मैन्युअल निर्माण, स्कोप की परिभाषा और प्रत्येक Android घटक में इंजेक्शन कॉन्फ़िगरेशन की आवश्यकता होती है। डेवलपर AppComponent, ActivityComponent, FragmentComponent बनाता है और @Subcomponent के माध्यम से उनके संबंधों का प्रबंधन करता है। यह दृष्टिकोण अधिकतम नियंत्रण देता है लेकिन महत्वपूर्ण boilerplate कोड की आवश्यकता होती है। Dagger का उपयोग बड़े प्रोजेक्ट्स में किया जाता है जिन्हें गैर-मानक DI आर्किटेक्चर की आवश्यकता होती है, या गैर-Android Java/Kotlin प्रोजेक्ट्स में।
Hilt boilerplate को स्वचालित करता है: एक @HiltAndroidApp, प्रत्येक घटक के लिए एक @AndroidEntryPoint, पूर्वनिर्धारित स्कोप। Google सभी नए Android प्रोजेक्ट्स के लिए Hilt की अनुशंसा करता है। Dagger से Hilt में माइग्रेशन में Component को @InstallIn से बदलना, @Subcomponent को पूर्वनिर्धारित Hilt घटकों से बदलना और मैन्युअल ViewModelProvider.Factory को @HiltViewModel से बदलना शामिल है। अधिकांश @Module क्लासेस को @Provides विधियों को बदले बिना @InstallIn जोड़कर माइग्रेट किया जाता है।
| विशेषता | Dagger | Hilt |
|---|---|---|
| सेटअप | मैन्युअल: Component, Subcomponent, Builder | स्वचालित: @HiltAndroidApp, @AndroidEntryPoint |
| Android घटक | कोई पूर्वनिर्धारित नहीं | 12+ अंतर्निहित घटक |
| ViewModel | मैन्युअल फैक्ट्री | @HiltViewModel + @Inject constructor |
| मल्टीमॉड्यूल | @Component(dependencies) के माध्यम से | @InstallIn + एकत्रीकरण के माध्यम से |
| जटिलता | उच्च — अनुभव आवश्यक | निम्न — सहज रूप से समझने योग्य |
| लचीलापन | अधिकतम | मानक (95% परिदृश्यों को कवर करता है) |
Hilt की सीमाएँ: लाइब्रेरी केवल Android का समर्थन करती है (शुद्ध सर्वर-साइड Java प्रोजेक्ट्स के लिए उपयुक्त नहीं), एक निश्चित घटक संरचना लागू करती है (ओवरराइड करना कठिन), और Jetpack Compose प्रोजेक्ट्स के लिए android.hilt:hilt-navigation-compose पर निर्भरता जोड़ती है। Compose एप्लिकेशन के लिए, Hilt @HiltViewModel प्रदान करता है जो Composable में hiltViewModel() के माध्यम से सुलभ है — Activity से मैन्युअल ViewModel प्रावधान के बिना।
अक्सर पूछे जाने वाले प्रश्न
Dagger मैन्युअल Component और Module कॉन्फ़िगरेशन के साथ एक बुनियादी कंपाइल-टाइम DI फ्रेमवर्क है। Hilt Android के लिए एक आवरण है जो घटक निर्माण और Activity, Fragment, ViewModel, Service और BroadcastReceiver के जीवनचक्र के साथ एकीकरण को स्वचालित करता है।
@HiltAndroidApp Application के लिए Hilt घटक जनरेशन को सक्षम करता है। इस एनोटेशन के बिना, Hilt मूल SingletonComponent नहीं बना सकता जिससे सभी ActivityComponent, FragmentComponent और ViewModelComponent प्राप्त होते हैं। एनोटेशन किसी भी Hilt प्रोजेक्ट के लिए अनिवार्य है।
Hilt Navigation NavBackStackEntry में ViewModel के लिए @HiltViewModel और नेविगेशन ग्राफ के भीतर ViewModel को स्कोप करने के लिए hiltNavGraphViewModels() प्रदान करता है। android.hilt:hilt-navigation-fragment लाइब्रेरी प्रत्येक NavBackStackEntry के लिए स्वचालित रूप से ViewModel बनाती है।
एप्लिकेशन Context के लिए @ApplicationContext या Activity Context के लिए @ActivityContext का उपयोग करें। Hilt android.hilt:hilt-android लाइब्रेरी में ये क्वालिफायर अंतर्निहित प्रदान करता है। @ActivityContext केवल ActivityComponent में स्थापित मॉड्यूल में उपलब्ध है।
@Binds @Provides का एक कुशल विकल्प है जब कोई विधि ठीक एक पैरामीटर स्वीकार करती है और उसके प्रकार को इंटरफ़ेस के रूप में लौटाती है। @Binds विधि को कॉल किए बिना प्रत्यक्ष कास्ट जनरेट करता है, जनरेटेड कोड की मात्रा कम करता है और इंजेक्शन प्रदर्शन में सुधार करता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें