搜尋套件、儲存庫與 APP 分類

套件詳情v1.1.0

gate_generator

用於您 Flutter/Dart 應用程式的依賴注入產生器。此工具使用註解和 build_runner。

macOSWindowsLinux
近 30 天下載
52
喜歡數
22
Pub 分數
120

安裝套件

flutter pub add gate_generator

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

Gate Generator 是一個用於 Flutter 和 Dart 應用程式的依賴注入程式碼產生器,利用註解和 build_runner 自動產生樣板程式碼。它透過分析帶有註解的類別,在編譯時期產生必要的註冊與解析邏輯,從而簡化依賴注入的設定。這能減少執行時間開銷並提升類型安全性。該工具可輕鬆整合至現有專案中,設定極少,非常適合可擴展且易於維護的應用架構。

適用情境

  • 自動化依賴注入設定
  • 減少手動 DI 的樣板程式碼
  • 提升應用可擴展性
  • 啟用類型安全的服務解析
  • 支援模組化應用設計

主要特色

  • 基於註解的設定
  • 建構執行器整合
  • 編譯時期程式碼產生
  • 最小的執行時開銷
  • 類型安全的依賴項解析

適合對象

  • 大規模 Flutter 應用
  • 重視可維護性的團隊
  • 使用乾淨架構的專案
  • 尋求自動化依賴注入設定的開發者
  • 需要高可測試性的應用

使用建議

  • 需要設定 build_runner
  • 僅限編譯時期產生
  • 依賴於正確註解的使用
  • 可能會稍微增加建構時間
  • 不適用於動態依賴注入情境

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

flutter anchored onboarding screen

pubdev ci License: MIT

💎  Features

  • Provide Injectable as a singleton
  • Provide Injectable as a dynamic service
  • Inject an Injectable class into another

💡  Motivation

Providing Service should be independent from your pages or other code.

The DI pattern separates the responsibility of creating an object of the service class out of the client class. Also using code generation we can get rid of the boilerplate part.

🚀  Getting started

install gate with build_runner in you pubspec.yaml

dependencies:
  build_runner: ^X.X.X
  gate: ^X.X.X

dev_dependencies:
  gate_generator: ^X.X.X

Note: replace X.X.X with last available version on pub.dev.

📖  Usage

1. Create a class you want to inject
import 'package:gate/gate.dart';

@Injectable()
class CoffeeService {
  final S1 s1;

  CoffeeService._(this.s1);

  @Singleton()
  factory CoffeeService.simple(S1 s1) => CoffeeService._(s1);

  void pump() {
    print("CoffeeService it's working");
  }
}

You just have to

  • add @Injectable() above your class
  • add @Singleton() or @Provide() above a factory
2. Inject dependency

We can now inject our Injectables using @Inject annotation.

InjectedChild use

  • Type you want to inject
  • the name of the factory you want to use (you can have multiple provided factories)
  • the attribute name (just in case you want to rename it or make it private...)
import 'package:gate_example/gate/gate_provider.dart';
import 'package:gate_example/gate/coffee_service.dart';
part 'coffee_page.gate_inject.g.part';

@Inject(children: [
  InjectedChild(S1, factoryName: "build"),
  InjectedChild(CoffeeService, factoryName: "simple", attrName: "coffeeService"),
])
class CoffeePage extends StatelessWidget {
  const CoffeePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    coffeeService.pump();
    return Container();
  }
}

You can inject as many dependency as you want into your class as long as their are Injectable.

part 'coffee_page.gate_inject.g.part'; will be be added to your file this file will be genererated on next step don't forget to import "gate_provider.dart" that is generated next

3. Generate code

Using build runner you can run the command in your shell

flutter packages pub run build_runner build --delete-conflicting-outputs

Once build runner is done, you can run your flutter app and use all injected class.

If you change your factory or wants to inject other class... just rerun the build_runner 😀

📗  Properties

Annotation Description
Injectable mark a class as containing Singleton or Provide factories
Singleton mark a factory as a Singleton Injectable
Provide mark a factory as a Dymamic Injectable. Each time you inject will create a new instance of that class
Inject mark a class to inject dependencies
Inject annotation
Property Description
children a list of InjectedChild
InjectedChild annotation
Property Description
type The type to inject
factoryName The factory name to use
attrName (optionnal) The attribute name to call it from your class

✅  Tests

Run tests
dart pub global activate coverage
dart test --coverage="coverage"
format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib
Mock an injected dependency for testing

To remplace your service by mocks, you have to set them, before testing. Gate will generate all methods for you.

First, declare your mocked services with your preferred libraries.

Then use the appProvider to set mocks.

Finally, don't forget to reset mocks by setting them to null.

class CoffeeServiceMock extends Mock implements CoffeeService {}

class S1ServiceMock extends Mock implements S1 {}

class S2BServiceMock extends Mock implements S2B {}

class TodoServiceMock extends Mock implements TodoService {}

void main() {
  // Initialize mocks
  final CoffeeService coffeeServiceMock = CoffeeServiceMock();
  final S1 s1ServiceMock = S1ServiceMock();
  final S2B s2BServiceMock = S2BServiceMock();
  final TodoService todoServiceMock = TodoServiceMock();

  group('Mock injection group', () {
    setUp(() {
      when(() => coffeeServiceMock.getMenu()).thenReturn("Best menu");
      // Set injected services with mocks
      appProvider.setCoffeeServiceSimpleMock(coffeeServiceMock);
      appProvider.setS1BuildMock(s1ServiceMock);
      appProvider.setS2BBuildMock(s2BServiceMock);
      appProvider.setTodoServiceBeanMock(todoServiceMock);
    });

    tearDownAll(() {
      // Remove mocks from appProvider (real ones will be used)
      appProvider.setCoffeeServiceSimpleMock(null);
      appProvider.setS1BuildMock(null);
      appProvider.setS2BBuildMock(null);
      appProvider.setTodoServiceBeanMock(null);
    });

    test('Test mocks injection', () async {
      expect(appProvider.getCoffeeServiceSimple().getMenu(),
          equals('Best menu')); // Mocked returned value

      appProvider.setCoffeeServiceSimpleMock(null);

      expect(appProvider.getCoffeeServiceSimple().getMenu(),
          equals('No menu')); // True value (not mocked)
    });
  });
}

📣  Sponsor

logo apparence io

Initiated and sponsored by Apparence.io.

👥  Contribution

Contributions are welcome. Contribute by creating a PR or create an issue 🎉.

所屬分類

依賴

依賴清單 11 項

原始碼儲存庫

使用此套件的專案

暫無相關資料。