Кинжал зачем создавать пользовательские рамки - PullRequest
0 голосов
/ 29 августа 2018

Я изучаю кинжал и нашел эту статью , в которой объясняется, как использовать android.dagger, для меня все ясно, за исключением пользовательских областей видимости. Ранее я видел множество учебных пособий, в которых создавалась настраиваемая область действия для создания зависимостей от конкретных ситуаций (например, область входа в систему). Но этот урок показал мой другой подход. Вот мой пример: У меня есть класс, который должен быть создан только для MainActivityMasterActivity), но не для LoginActivity

class SecretKey(
    val token: String,
    val userId: Long
)

Итак, вот модуль

@Module
class MainActivityModule {
    @Provides
    fun provideSecretKey(preference: SharedPreferences): SecretKey {
        return SecretKey(
            "jwtToken",
            465465
        )
    }
}

и ActivityBindingModule

@Module
abstract class ActivitiesBindingModule {
    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    abstract fun mainActivity(): MainActivity

    @ContributesAndroidInjector(modules = [LoginActivityModule::class])
    abstract fun loginactivity(): LoginActivity

    // MasterActivity will see everything from MainActivityModule and LoginActivityModule
    @ContributesAndroidInjector(modules = [MainActivityModule::class, LoginActivityModule::class])
    abstract fun masterActivity(): MasterActivity
}

Так как я понял только в MainActivity и MasterActivity, я смогу внедрить класс SecretKey из-за модуля ContributesAndroidInjector. Таким образом, область действия SecretKey находится в пределах MainActivity и MasterActivity. Так почему же мы до сих пор можем создавать собственные области с аннотацией Scope? Это альтернатива?

1 Ответ

0 голосов
/ 30 августа 2018

Scope просто сообщает Dagger сохранить экземпляр аннотированного областью объекта , а не создавать новый. Кинжал сохранит экземпляр в компоненте соответствующей области видимости. (Вам также следует знать, что код @ContributesAndroidInjector создает для вас экземпляр подкомпонента, поэтому, если вы аннотируете метод @ContributesAndroidInjector аннотацией области действия, сгенерированный подкомпонент примет эту область.)

В вашем примере SecretKey не ограничен; каждый раз, когда вы просите Dagger ввести SecretKey, он будет вызывать ваш конструктор и создавать новый экземпляр. Это, вероятно, хорошо, поскольку SecretKey, похоже, не поддерживает состояние, а сохранение экземпляра scopeless позволяет сборщику мусора собирать SecretKey, когда он вам больше не нужен.

Однако представьте, что вы создаете свой собственный объект Cache и хотите, чтобы этот Cache жил до тех пор, пока активность, но не дольше : каждый новый экземпляр Activity должен иметь свой собственный Cache. В отличие от SecretKey, вы не можете создавать свой собственный кэш каждый раз, когда его запрашиваете; вам нужно сохранить свой экземпляр кэша где-нибудь. Вы можете сделать это в качестве поля в самой Activity или создать экземпляр Module, который сохраняет значение экземпляра при первом вызове метода @Provides, но Dagger предпочитает, чтобы вы пометили привязку аннотацией области действия, которая соответствует компоненту. Это позволяет вам объявить и задокументировать, что привязка будет иметь то же время жизни, что и компонент, и упростить классификацию привязок как «Область применения», «Область действия», «Область фрагмента», «Область обслуживания» и т. д.

...