Плюс некоторая помощь в разделении бизнес-логики и упрощении кода…

Как это поможет?

Его быстро добавить, легко использовать и есть дополнительные функции

Решения для внедрения зависимостей выполняют некоторые из основных задач в наших приложениях, и у них обычно есть несколько общих черт:

  • Во-первых, они создают одну версию службы или контроллера, которая может использоваться в нашем коде.
  • Во-вторых, им требуется механизм для обнаружения или поиска этой службы или контроллера из любого места в нашем коде.

Например, AuthService может потребоваться на страницах входа, регистрации и профиля нашего приложения. Чтобы включить внедрение зависимостей, нам обычно нужно создать нашу AuthService до того, как она понадобится какой-либо из этих страниц, а затем эти страницы будут использовать какой-то локатор или поисковик. для доступа к таким методам, как getuser() в AuthService.

Наше решение для внедрения зависимостей избавляет от необходимости писать этот локатор / искатель и дает некоторые дополнительные преимущества, которые также могут ускорить разработку вашего приложения.

Что мне нужно?

На самом деле не слишком много

Мы собираемся использовать пакет под названием Get. Почему именно этот пакет? По словам автора пакета:

«Get - это микрофреймворк для Flutter»

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

Запустить таймер

ШАГ 1 - добавьте Get в pubspec.yaml и импортируйте его в наше приложение.

ШАГ 2 - измените наш MaterialApp на GetMaterialApp.

Микрофреймворк Get теперь доступен для нас.

ШАГ 3 - добавьте наши услуги.

Мы собираемся опробовать внедрение зависимостей на двух сервисах. Сначала мы немедленно создадим экземпляр TestService.

Во-вторых, мы выполним отложенное создание экземпляра на AuthService, что означает, что служба не будет создана, пока она не понадобится. Обычно считается хорошим тоном использовать этот метод, если вам не нужен немедленный доступ к службе.

Любой способ хорош, и вот как это выглядит.

ШАГ 4 - внедряем наши сервисы.

Так же, как есть два способа создать экземпляр службы для инъекции, Get - это два способа внедрить зависимость:

  • Первый использует статический метод в начале внедряемого класса - мы будем использовать его для внедрения TestService.
  • Для второго требуется объявление типа ‹›, чтобы квалифицировать внедрение - мы будем использовать его для внедрения AuthService.

Я считаю, что первый метод легче читать, но производительность идентична.

И мы закончили

Теперь у нас есть полностью функционирующее решение для внедрения зависимостей с двумя внедренными сервисами, которые представляют свой вывод через SnackBar в 65 строках!

Вот фрагмент нашего кода.

Абстрактные классы и тестирование

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

Вот абстрактный класс MyService, расширенный нашим кодом реализации:

  • Get.lazyPut<MyService>(() => MyServiceImpl());

А вот тот же абстрактный сервис, расширенный с помощью класса тестирования Mock:

  • Get.lazyPut<MyService>(() => MyServiceMock());

В любом случае, наш вызов MyService такой же:

  • MyService.to.multiply(2, 3);

Я включил суть примера здесь, спасибо Стефану де Фогеларе за его помощь и пример.

Что еще я могу сделать?

Несколько дополнительных бонусов поставляются с нашим решением DI

Давайте сделаем несколько вещей, чтобы сделать наш код более простым для написания и чтения.

Бонус 1 - Помогите разделить нашу бизнес-логику

Обратите внимание, я сказал «помогите». Это не решение для управления состоянием (хотя у Get их два), оно скорее поможет вам с некоторыми вещами, которые вы, возможно, захотите делать из классов бизнес-логики.

Скажем, например, наша Business Logic TestService должна представить DialogBox, SnackBar или BottomSheet? Давайте попробуем с тем SnackBar, который мы использовали ранее.

Мы удалим виджет Builder и следующую строку showSnackBar из StatefulWidget на нашей TestPage:

  • Scaffold.of(context).showSnackBar(SnackBar(content: Text(result))

После этого мы просто добавляем следующую строку в нашу TestService:

Get.snackBar("TestService", result)

Вы заметили, что мы сделали это без ссылкиcontext?

Мы также могли бы сделать это из нашего StatefulWidget, если бы не хотели переносить SnackBar в нашу бизнес-логику. Он по-прежнему намного чище, чем исходный код, и не требует context или Builder виджета над ним.

Это отличный инструмент для разделения задач в таких архитектурах, как MVVM, BLoC и MVC.

Бонус 2 - Упростите этот синтаксис

Давайте будем честными, Flutter иногда может быть многословным, поэтому все, что может упростить эти вызовы для получения значения из theme или context, хорошо.

Допустим, мы хотим получить высоту страницы. Это было бы:

  • MediaQuery.of(context).size.height;

С помощью Get это становится:

  • Get.height;

Теперь посмотрим, активна ли темная тема:

  • MediaQuery.of(context).platformBrightness == Brightness.dark
    ? true : false;

И с помощью Get:

  • Get.isDarkMode;

Писать чище и быстрее. Это лишь некоторые из удобных оболочек, которые предоставляет Get.

Вот часть нашего обновленного кода. Как видите, наш SnackBar выглядит немного иначе, и его тоже можно настроить.

Итак, мы создали полнофункциональное приложение для демонстрации внедрения зависимостей, разделения проблем и небольшой очистки кода, но у нас все еще менее 100 строк!

Суть нашего кода вы можете найти здесь.

Как это возможно?

Пожалуйста, объясните

Когда мы перешли с MaterialApp на GetMaterialApp, мы передали Get руководство над context и основным виджетом в нашем приложении. С этого момента мы могли просто вызывать Get из любого места нашего кода, чтобы все происходило.

Когда мы использовали Get.put для создания наших TestService и Get.lazyPut на нашем AuthService, мы фактически создавали их экземпляры внутри экземпляра Get. После добавления GetMaterialApp эти службы стали доступны в любом месте нашего приложения.

Такие вещи, как Get.length, просто удобные оболочки для стандартных методов Flutter, к которым мы получаем доступ через Get.

Get.snackbar работает так же, но предлагает более настраиваемое и визуально привлекательное решение, чем его стандартный аналог Flutter.

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



Итак, как мы это сделали?

Добавлена ​​инъекция зависимостей всего несколькими строками кода? Ага.

Нашли простой способ удалить часть этой бизнес-логики с наших страниц Flutter? Ага.

Сделали наш код немного проще для глаз и более понятным для написания? Ага.

Наслаждаться.