Dart/Flutter Dependency injection generator

flutter anchored onboarding screen

pubdev ci License: MIT


Providing Service should be independant 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.


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

Getting started

install gate with build_runner in you pubspec.yaml

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

  gate_generator: ^X.X.X

replace X.X.X with last available version on


1 - Create a class you want to inject

import 'package:gate/gate.dart';

class CoffeeService {
  final S1 s1;


  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);

  Widget build(BuildContext context) {
    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 :)


Injectablemark a class as containing Singleton or Provide factories
Singletonmark a factory as a Singleton Injectable
Providemark a factory as a Dymamic Injectable. Each time you inject will create a new instance of that class
Injectmark a class to inject dependencies

Inject annotation

childrena list of InjectedChild

InjectedChild annotation

typeThe type to inject
factoryNameThe factory name to use
attrName(optionnal) The attribute name to call it from your class

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 prefered 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

    tearDownAll(() {
      // Remove mocks from appProvider (real ones will be used)

    test('Test mocks injection', () async {
          equals('Best menu')); // Mocked returned value


          equals('No menu')); // True value (not mocked)

Run tests

dart pub global activate coverage
dart test --coverage="coverage"
format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib


To be done logo

Developed with 💙  by