Внедрение зависимости от трепета

Внедрение зависимости от трепета

7 августа 2025 г.

Прежде чем продолжить эту статью, убедитесь, что у вас есть четкое представление о том, что такое зависимость и какова инъекция зависимости.

По мере того, как ваше приложение Flutter растет, управление услугами, такими как API, хранение, аутентификация и бизнес -логика, становится все труднее и требует более чистого способа внедрить все зависимости в ваше приложение без необходимости вручную передавать объекты через конструкторы или деревья виджетов.

Вот гдеGetItВходит. Это простой и очень мощный пакет локаторов обслуживания и делает инъекцию зависимостей чистым, централизованным и легким. Это приводит к:

  • Более чистый код
  • Более легкое тестирование
  • Лучшая масштабируемость

Зачем инъекции зависимости?

Инъекция зависимостей отделяет проблемы в вашем приложении и позволяет вам центрально вводить зависимости без необходимости проходить их для зависимых классов отдельно.

Инъекция зависимости-общие способы

Наиболее часто используемые способы впрыскивания зависимостей в трепетание - через конструктор и сеттер, его простые и простые для понимания и полезные в небольших проектах. Для понимания целей мы рассмотрим примерApiServiceкласс, как упомянуто ниже:

class ApiService {
  void fetchData() {
    print('Fetching data...');
  }
}

Теперь давайте посмотрим на инъекцию конструктора и инъекцию сеттера с помощью этогоApiServiceсорт.

Инъекция конструктора

Как упоминается имя, инъекция конструктора относится к процессу передачи зависимостей через конструкторы класса. Рассмотрим пример ниже для лучшего понимания:

class HomeController {
  final ApiService apiService;

  // Constructor injection
  HomeController(this.apiService);
}
void main() {
  final apiService = ApiService();                 // Create dependency
  final controller = HomeController(apiService);   // Inject via constructor
}

Как вы можете видеть в примере выше, зависимостьApiServiceбыл передан вHomeControllerИспользование конструктораHomeControllerсорт.

Инъекция сеттера

Инъекция сеттера - это процесс передачи зависимостей с помощью сеттера. Рассмотрим пример ниже для лучшего понимания:

class HomeController {
  ApiService? _apiService;

  // Setter injection
  set apiService(ApiService service) {
    _apiService = service;
  }
}
void main() {
  final apiService = ApiService();
  final controller = HomeController();

  controller.apiService = apiService; // Inject after construction
}

В примере выше, сеттерapiServiceиспользуется для передачи зависимостиHomeControllerПолем

Теперь, когда мы видели общие способы инъекций зависимостей, давайте теперь проведем инъекцию зависимостейGetItПакет в пошаговом гиде.

Шаг 1: добавитьget_itк вашему проекту

Добавлятьget_it: latest_versionв ваш проектpubspec.yamlФайл, как ниже:

dependencies:
  get_it: ^7.6.0

Шаг 2: Создание и регистрация служб

Предположим, у нас есть услуга API

class ApiService {
  void fetchData() {
    print('Fetching data...');
  }
}

Теперь давайте создадим локатор сервиса:

import 'package:get_it/get_it.dart';

final getIt = GetIt.I;

void setupLocator() {
  getIt.registerLazySingleton<ApiService>(() => ApiService());
}

Теперь позвоните в этот локатор услуг в своемmain()доrunApp()

void main() {
  setupLocator();
  runApp(MyApp());
}

Шаг 3: Используйте сервис в любом месте

Теперь вы можете использовать инъекционныеApiServiceв любом месте вашего проекта, используяGetIt.I.<ApiService>()без необходимости переосмыслить его. Ниже приведен пример этого:

class HomeScreen extends StatelessWidget {
  final api = GetIt.I.get<ApiService>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => api.fetchData(),
          child: Text('Fetch Data'),
        ),
      ),
    );
  }
}

ОбзорGetItМетоды регистрации

Ниже приведена таблица основных методов регистрации, доступная вGetIt:

Метод

Описание

Использование

registerSingleton<T>(T)

Регистрирует уже созданный экземпляр. Мгновенно доступен.

Легкие услуги необходимы немедленно (например, конфигурация).

registerLazySingleton<T>()

Регистрирует фабричную функцию. Экземпляр созданна первом доступе, затем повторно использовал.

Тяжелые или редко используемые услуги (например, дБ, сеть).

registerFactory<T>()

Возвращает ановый экземпляркаждый разget<T>()называется.

Блоки, контроллеры или что-нибудь недолгое.

registerSingletonAsync<T>()

Регистры Anасинхрофабрика. Экземпляр ожидается во времяget<T>()Полем

Услуги, которые требуют асинхронной настройки (например, чтение с диска).

registerFactoryAsync<T>()

Возвращает ановый экземпляр Asyncкаждый раз.

Свежие асинхронные экземпляры для использования (менее распространены).

Тестирование с инъекцией зависимостей

Как упоминалось ранее, инъекция зависимостей также облегчает проверку нашего кода, мы увидим его в действии сейчас. Предположим, у нас есть контроллер, который зависит отApiService():

class HomeController {
  final ApiService apiService;
  HomeController(this.apiService);
}

Для тестирования мы будем использовать фиктивную службу API, которая будет проститься отApiService():

class MockApiService extends ApiService {
  @override
  void fetchData() {
    print('Mock fetch');
  }
}

void main() {
  final controller = HomeController(MockApiService());
  controller.apiService.fetchData();
}

Нет необходимости изменять код Apiservice (), проходная зависимость через конструктор будет хорошо запускать наши тесты.

Обычные методы против getit

Особенность

Обычный ди

Возьми

Видимость зависимости

Прозрачный

Скрытый (глобальный поиск)

Тестируемость

Очень хороший

Нужно больше настройки

Шаблон

Выше

Минимальный

Глобальный доступ

Нет

Да

Весы хорошо

Нет (без дополнительных инструментов)

Да

Нулевая безопасность

Сильный

Зависит от использования

Необходимы внешние пакеты

Нет

Да (get_it)

Lazy/Singleton Rading

Руководство

Встроенный

Когда использовать что?

Традиционные методы инъекции зависимостей лучше всего работают, когда:

  • Тестируемость является приоритетом
  • Приложение мало масштабируется
  • Вы не хотите полагаться на сторонние пакеты

GetItработает лучше всего, когда:

  • Приложение увеличивается по размеру и сложности
  • Есть много глобальных зависимостей, чтобы положиться на
  • Хочу сохранить дерево виджетов в чистоте, избегая передачи зависимостей через конструкторы

Лучшие практики и советы

  • Не регистрируйте все в Getit, только общие зависимости
  • Предпочитаю использоватьregisterFactoryПри использовании переходной логики, такой как блок
  • Не забудьте позвонитьGetIt.I.reset()в настройке теста для изоляции

Последние мысли

Инъекция зависимости играет ключевую роль в создании масштабируемого, тестируемого и простых в управлении кодом. Он очищает ваши классы, разделяя конфигурации и логику и при использовании мощного локатора обслуживания, какGetItзависимости вашего проекта становятся централизованно управляемыми, и это заставляет вас обходить необходимость передавать зависимости через конструкторы, поскольку у вас есть доступ к зависимостям во всем мире. Кроме того, это увеличивает тестируемость кода.

Таким образом, сочетание принципов инъекции зависимости сGetItНе только способствует более чистой архитектуре, но и повышает скорость развития, повышает модульность и готовит вашу кодовую базу для долгосрочного роста.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE