Я понимаю твои разочарования.Я был там раньше, и мне потребовалось довольно много времени, чтобы понять сам кинжал.Просто быстрая демонстрация / учебник.
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
fun context(): Context
}
@Module
class AppModule(private val application: Application) {
@Provides
@Singleton
fun provideApplication(): Application= application
}
Компонент - это интерфейс к контейнеру.Все, что определено здесь, может быть доступно, если вы можете успешно создать экземпляр своего контейнера.Кроме того, это интерфейс для других контейнеров / компонентов.Это означает, что если вы хотите выставить что-то вне вашего контейнера, вы определяете это здесь.Следовательно,
Почему, черт возьми, мне нужно один раз предоставить зависимость в модуле, а в другой раз определить ее в компоненте.Это просто глупо.
не всегда верно.Вам не нужно ничего определять в вашем компоненте, если вы не хотите, чтобы что-то открывалось снаружи.Альтернативой экспонированию может быть инъекция.
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
fun inject(activity: MainActivity)
}
Здесь вы ничего не выставляете, но вы все равно можете получить контекст действия из контейнера через инъекцию.
Теперь давайте перейдем к определению области.
Scoping - это способ предоставления «локальных синглетонов» внутри вашего контейнера.Зависимость по объему будет создана только один раз внутри контейнера.Примером является ваша область действия PerActivity.Компонент с областью действия принимает только модуль с той же областью действия.Например:
@PerActivity
@Component(dependencies = [AppComponent::class],
modules = [ActivityModule::class])
interface ActivityComponent{
fun inject(activity: MainActivity)
}
Соответствующий модуль должен быть ограничен только PerActivity.
class ActivityModule(activity:Activity) {
@PerActivity
@Provides
fun provideActivity() = activity
}
Любая другая область, определенная в вашем модуле, которая не совпадает с областью, в которой вы планируете компонентприведет к ошибке компиляции.Использование нескольких областей также не допускается.
Что касается зависимостей компонентов, вы можете использовать dependencies
или subcomponents
.Если используются зависимости, любая зависимость, которая требуется дочернему элементу, должна быть раскрыта родителем.В нашем случае выше, если ActivityComponent требует контекста активности, AppComponent должен определить функцию, которая его возвращает.В подкомпонентах просто укажите свой подкомпонент в своем компоненте, и зависимости будут разрешены внутри.
Я написал небольшое руководство по изучению кинжала 2. Если вам интересно, вы можете проверить его.https://medium.com/tompee/android-dependency-injection-using-dagger-2-530aa21961b4 https://medium.com/tompee/dagger-2-scopes-and-subcomponents-d54d58511781