What is Flutter Injectable?
In the world of software development, Dependency Injection (DI) is a powerful design pattern that promotes modular, scalable, and maintainable code. In Flutter, managing dependencies can sometimes become challenging, especially in large applications. This is where Injectable comes in a code generator for handling dependency injection in Flutter, built on top of the popular get_it
package.
In this blog, we’ll dive deep into Flutter Injectable, exploring how it simplifies dependency injection, enhances your Flutter projects, and provides practical examples to get you started.
What is Dependency Injection?

Before we jump into Injectable, let’s briefly recap what Dependency Injection is:
Dependency Injection is a technique where an object receives its dependencies from an external source rather than creating them itself. This promotes loose coupling between classes and makes the code easier to test and maintain.
In simpler terms, instead of a class creating its instances of dependencies, those dependencies are injected into the class from outside, usually by a DI container.

Why Use Injectable in Flutter?
While Flutter provides several ways to manage dependencies, manually injecting dependencies can lead to boilerplate code, especially as your application grows. Injectable, combined with get_it
, streamlines this process by auto-generating the necessary code to manage your dependencies efficiently.
Key benefits of using Injectable:
- Auto-Generated Code: Injectable auto-generates code for DI, reducing boilerplate and potential errors.
- Scalability: Manages dependencies across large codebases seamlessly.
- Modularity: Promotes modular architecture, making it easier to test and maintain.
- Integration with GetIt: Seamless integration with
get_it
, a popular service locator in Flutter.
Setting Up Injectable in Flutter
Let’s walk through the steps to integrate Injectable into a Flutter project.
Step 1: Add Dependencies
First, add the necessary dependencies to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
get_it: ^7.2.0
injectable: ^2.0.0
dev_dependencies:
injectable_generator: ^2.0.0
build_runner: ^2.1.11
After adding the dependencies, run flutter pub get
to install them.
Step 2: Create the Injectable Configuration
Create a new Dart file named injection.dart
in the lib
folder. This file will configure Injectable and initialize get_it
:
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'injection.config.dart'; // generated file
final getIt = GetIt.instance;
@InjectableInit(
initializerName: r'$initGetIt', // default
preferRelativeImports: true, // default
asExtension: false, // default
)
void configureDependencies() => $initGetIt(getIt);
Step 3: Annotate Your Services
To inject dependencies, you need to annotate your classes. For example, let’s say you have a UserRepository
and a UserService
:
import 'package:injectable/injectable.dart';
@lazySingleton
class UserRepository {
// Your implementation
}
@injectable
class UserService {
final UserRepository userRepository;
UserService(this.userRepository);
// Your implementation
}
Here, @lazySingleton
tells Injectable to create a single instance of UserRepository
, which will be reused whenever it’s needed. The @injectable
annotation on UserService
ensures that it will be properly injected with its dependencies.
Step 4: Generate the DI Code
Now, let’s generate the code to wire everything together. Run the following command in your terminal:
flutter pub run build_runner build
This will generate the necessary code in the injection.config.dart
file.
Step 5: Use the DI in Your Flutter App
With everything set up, you can now inject dependencies in your Flutter widgets or other classes:
import 'package:flutter/material.dart';
import 'injection.dart';
import 'user_service.dart';
void main() {
configureDependencies();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final userService = getIt<UserService>();
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Injectable Example'),
),
body: Center(
child: Text('Welcome, ${userService.getUserName()}!'),
),
),
);
}
}
In this example, getIt<UserService>()
retrieves the instance of UserService
with all its dependencies automatically injected.
Advanced Usage of Injectable
Injectable is highly customizable and supports advanced features such as:
- Named Dependencies: You can have multiple implementations of the same interface by using named dependencies.
- Environment-Based Injection: Injectable allows you to define different sets of dependencies based on the environment (e.g., dev, prod).
- Modules: You can group dependencies into modules for better organization and reuse.
Conclusion
Injectable makes Dependency Injection in Flutter a breeze by automating the process of managing dependencies, reducing boilerplate code, and improving the scalability of your application. By following the steps outlined in this blog, you can integrate Injectable into your Flutter projects and take advantage of its powerful features.
Whether you’re building a small app or a large enterprise application, using Injectable ensures that your codebase remains clean, modular, and easy to maintain. Start using Injectable today and see the difference it makes in your Flutter development workflow!
Show Your Support


6 Responses