搜索插件、代码仓与 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 项

源码仓库

使用此插件的项目

暂无相关数据。