← Назад к вопросам

К какому scope привязан Singleton

1.0 Junior🔥 81 комментариев
#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Scope Singleton в Android и Dependency Injection

В контексте Dependency Injection (DI) фреймворков, таких как Dagger или Koin, Singleton — это не просто шаблон проектирования, а конкретный scope (область видимости/жизненного цикла), к которому привязывается время жизни объекта.

Ключевой принцип

Scope Singleton означает, что экземпляр класса создается ровно один раз и существует на протяжении всего жизненного цикла компонента, к которому он привязан. Это отличается от глобального синглтона (object в Kotlin), который живет всё время работы приложения.

Основные варианты Scope в Android

1. Application Scope (Глобальный Singleton)

Объект создается один раз и живет всё время жизни приложения (пока живет Application класс).

  • Пример в Dagger:
@Module
class AppModule {
    @Singleton
    @Provides
    fun provideRepository(): Repository {
        return RepositoryImpl()
    }
}

@Component(modules = [AppModule::class])
@Singleton
interface AppComponent {
    fun inject(activity: MainActivity)
}

Здесь Repository будет существовать, пока живет AppComponent (обычно привязан к Application).

2. Activity Scope

Объект живет, пока живет конкретная Activity. Уничтожается вместе с ней.

  • Пример в Dagger 2 (с использованием подкомпонентов):
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

@Module
class ActivityModule {
    @ActivityScope
    @Provides
    fun providePresenter(): Presenter {
        return Presenter()
    }
}

@Subcomponent(modules = [ActivityModule::class])
@ActivityScope
interface ActivityComponent {
    fun inject(fragment: MyFragment)
}

3. Fragment Scope и другие custom scopes

Аналогично можно создавать scope для Fragment, ViewModel, пользовательской сессии.

Почему Singleton — это Scope?

В Dagger/Hilt аннотация @Singleton — это просто предопределенный scope, который по умолчанию привязан к Application компоненту.

  • @Singleton ≠ вечный глобальный объект. Если компонент (например, ActivityComponent) будет уничтожен, все его синглтонные зависимости также станут недоступны и будут собраны GC.
  • Главное правило: время жизни объекта не может превышать время жизни его компонента.

Практическое значение

// БЕЗ DI (проблема: тестирование, жесткая связь)
object OldSingletonRepo {
    fun getData() {}
}

// С DI и Scope (гибко, тестируемо)
class MyRepository @Inject constructor() {
    fun getData() {}
}

// В модуле Dagger/Hilt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Singleton
    @Provides
    fun provideRepo(): MyRepository = MyRepository()
}

Ключевые выводы:

  1. Singleton в DI — это всегда scope, а не просто паттерн.
  2. Объект живет столько же, сколько и компонент, к которому он привязан.
  3. В Android чаще всего используют:
    • @Singleton для глобальных зависимостей (база данных, API клиент)
    • @ActivityScoped для зависимостей, нужных только в рамках активити
    • @ViewModelScoped в Hilt для зависимостей ViewModel
  4. Никогда не смешивайте DI-синглтоны с глобальными object — это нарушает принцип инверсии зависимостей и усложняет тестирование.

Таким образом, Singleton привязан к scope своего DI-компонента, и именно это определяет его жизненный цикл в современной Android-архитектуре.