DEV Community

Cover image for Applying Dependency Injection in Flutter Using Injectable
Vishnu C Prasad
Vishnu C Prasad

Posted on • Originally published at vishnucprasad.Medium

Applying Dependency Injection in Flutter Using Injectable

Dependency injection (DI) is a design pattern that promotes loose coupling and enhances the modularity and testability of your code. In the world of Flutter development, dependency injection becomes a crucial tool for managing the dependencies in a clean and efficient manner. One popular package for implementing dependency injection in Flutter is injectable. In this article, we will explore how to apply dependency injection in Flutter using the injectable package.

What is Dependency Injection?

Dependency injection is a software design pattern where the components of a system are loosely coupled by injecting dependencies rather than hardcoding them within the components. This makes the system more modular, flexible, and easier to test.

In Flutter, dependencies might include services, repositories, or any other classes that a widget relies on to perform its tasks. Instead of creating instances of these dependencies directly within a widget, dependency injection allows us to provide these instances from the outside, making our code more maintainable and scalable.

Using the injectable Package

The injectable package is a powerful and easy-to-use dependency injection package for Flutter. It provides a simple and concise syntax for defining and injecting dependencies. To get started, add the following dependencies to your pubspec.yaml file:

dependencies:
  injectable:  
  get_it:

dev_dependencies:
  injectable_generator:
  build_runner:
Enter fullscreen mode Exit fullscreen mode

Now, run flutter pub get to fetch the dependencies.

Setting up injectable

Once the dependencies are added, you need to set up injectable in your project. Create a new file called injection.dart in your project's root directory. This file will contain the configuration for injectable.

// injection.dart

import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';

import 'injection.config.dart';

final GetIt getIt = GetIt.instance;

@injectableInit
Future<void> configureDependencies(String env) async {
  getIt.init(environment: env);
}
Enter fullscreen mode Exit fullscreen mode

This file initializes the GetIt instance and sets up the necessary configuration for injectable.

Defining Dependencies

Now, let’s define some dependencies. Create a new folder named injections and inside it, create a file named injection_container.dart. This file will contain the configuration for your dependencies.

// injections/injection_container.dart

import 'package:injectable/injectable.dart';

@module
abstract class InjectableModule {
  // Define your dependencies here
  // Example:
  // @lazySingleton
  // YourDependency get yourDependency => YourDependency();
}
Enter fullscreen mode Exit fullscreen mode

In this file, you can define your dependencies using the @lazySingleton, @singleton, @factoryMethod, and other annotations provided by injectable. For example, a simple dependency might look like this:

@lazySingleton
YourDependency get yourDependency => YourDependency();
Enter fullscreen mode Exit fullscreen mode

Generating Code
To generate the necessary code for injectable, run the following command in your terminal:

flutter packages pub run build_runner build --delete-conflicting-outputs
Enter fullscreen mode Exit fullscreen mode

This command triggers the code generation process and generates the necessary files for dependency injection.

Using Dependencies in Widgets

Now that your dependencies are set up, you can use them in your widgets. Import the injection.dart file and call the configureDependencies function in your main.dart file:

// main.dart

import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';
import 'injection.dart';

void main() {
  configureDependencies(Environment.prod);
  runApp(MyApp());
}
Enter fullscreen mode Exit fullscreen mode

Now, you can use the getIt instance to access your dependencies in any widget:

// example_widget.dart

import 'package:flutter/material.dart';
import 'injection.dart';

class ExampleWidget extends StatelessWidget {
  final YourDependency yourDependency = getIt<YourDependency>();

  @override
  Widget build(BuildContext context) {
    // Use yourDependency here
    return Container();
  }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Dependency injection is a powerful pattern that can greatly improve the structure and testability of your Flutter applications. The injectable package provides a convenient way to implement dependency injection in your projects. By separating concerns and promoting modular code, you can create more maintainable and scalable Flutter applications.

Top comments (0)