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

Что такое @Module?

2.0 Middle🔥 133 комментариев
#Dependency Injection

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

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

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

Что такое @Module в Dagger?

@Module — это аннотация в библиотеке внедрения зависимостей Dagger, которая отмечает класс, содержащий методы для предоставления зависимостей. Этот класс выступает в роли "фабрики" или "поставщика" объектов, которые затем могут быть внедрены в другие части приложения.

Основное назначение и принцип работы

Класс, помеченный @Module, содержит методы, аннотированные @Provides, @Binds или @Multibinds. Эти методы определяют, как создавать и предоставлять конкретные экземпляры зависимостей, когда Dagger строит граф объектов.

@Module
class NetworkModule {

    @Provides
    fun provideHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .build()
    }

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

Ключевые характеристики @Module

  • Абстрагирование логики создания: Модули инкапсулируют сложную логику инициализации объектов (например, настройку сетевых клиентов, баз данных, репозиториев). Это делает код чище и переиспользуемым.
  • Управление областью видимости (Scope): Модули часто используются вместе с пользовательскими скоупами (например, @Singleton, @ActivityScope), чтобы контролировать жизненный цикл создаваемых объектов — будет ли это один экземпляр на все приложение, на активити или новый инстанс при каждом запросе.
    @Module
    @InstallIn(SingletonComponent::class) // Область видимости — уровень приложения
    object AppModule {
        @Singleton // Один экземпляр на всё приложение
        @Provides
        fun provideDatabase(@ApplicationContext context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, "app.db").build()
        }
    }
    
  • Организация и модульность: Приложение может состоять из множества модулей, каждый из которых отвечает за свою предметную область (сеть, база данных, аналитика). Это соответствует принципам чистой архитектуры.
  • Разрешение зависимостей: Методы внутри модуля могут иметь параметры. Dagger автоматически находит и предоставляет эти параметры (зависимости) из графа, что позволяет строить цепочки зависимостей.

Типы модулей в современном Dagger (Hilt)

В Dagger Hilt (рекомендуемой надстройке над Dagger для Android) модули стали более структурированными благодаря аннотации @InstallIn.

// Модуль, доступный на уровне всего приложения
@Module
@InstallIn(SingletonComponent::class)
object AppModule { /* ... */ }

// Модуль, доступный только в пределах Activity
@Module
@InstallIn(ActivityComponent::class)
object ActivityModule { /* ... */ }

// Модуль, доступный только в пределах ViewModel
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule { /* ... */ }

Преимущества использования

  • Тестируемость: Модули легко подменять на тестовые (через @TestInstallIn в Hilt), что позволяет внедрять mock- или stub-зависимости.
  • Изоляция кода: Детали реализации создания объектов скрыты от потребителей.
  • Централизованное управление: Конфигурация и способ создания ключевых компонентов системы сосредоточены в одном месте, а не размазаны по кодовой базе.

Важные моменты на практике

  1. Статические vs. Нестатические методы: В Kotlin object (синглтон) подходит для большинства случаев, так как его методы по умолчанию статические. Если модуль — это обычный class, для производительности стоит отмечать методы @Provides как companion object или использовать @JvmStatic в Java.
  2. @Binds vs @Provides: @Binds используется для абстрактных методов, которые просто связывают интерфейс с его реализацией, что эффективнее. @Provides — для методов, содержащих логику создания экземпляра.
    @Module
    abstract class RepositoryModule {
    
        @Binds // Более эффективно, чем @Provides
        abstract fun bindUserRepository(impl: UserRepositoryImpl): UserRepository
    }
    
  3. Включение модулей в компонент: Модуль должен быть указан в аннотации @Component.modules (в чистом Dagger) или @InstallIn (в Hilt), чтобы Dagger знал о его существовании.

Таким образом, @Module является фундаментальным строительным блоком в Dagger, который структурирует процесс предоставления зависимостей, делая код более поддерживаемым, тестируемым и масштабируемым. Без модулей вся логика создания объектов пришлась бы на компоненты или даже на клиентский код, что свело бы на нет преимущества внедрения зависимостей.

Что такое @Module? | PrepBro