Dependency Injection In Multi-Module Flutter Project

Dependency Injection is one of the hot topics around developers in the software industry nowadays. From it is a plus point in job descriptions to now a mandatory skill requirement (rightly so).

When I started working in Flutter, Dependency Injection was one of the few things for which I wanted to find available solutions. During my search, I came up with a few packages like inject by google, get_it by flutter community and injectable (a code-gen for get_it).

At first glance, inject got me very fascinated. One, because it is from google. Two, because I coming from Android background has a very good understanding of dagger and inject is very similar to dagger. But the problem I found with inject was the lack of documentation and its git repository has been archived (meaning expect no support from the owner). These two problems were enough for me to decide inject is not something I can rely upon my production code (at least for now).

Then I started looking into get_it which is officially from the flutter community. It’s not a dependency injection but a service locator. But the problem with get_it was that, I had to register each class to a get_it instance in order to get its dependency. For a small project it may seem alright but as the project scale bigger and bigger and the number of class grows along with it. Then its implementation will become spaghetti and with lots of boilerplate code.

At last, comes the injectable package. injectable is nothing special, it’s just a simple code generator for get_it package. Meaning, developer’s won’t be registering each class into get_it , injectable will auto-generate a dart file will all get_it registrations/implementation.

Photo by bruce mars on Unsplash

Problem solved? hmm… not so.

Now the problem comes with a multi-module project. Say you have a separate feature module in the flutter application and it is integrated into your pubspec.yaml file. There is no much documentation that can be found to use single/main injectable configuration (or at-at least having an option) to register feature module dependencies as well.

Since it’s not a detailed article on get_it and injectable but a solution to a multi-module project using the following packages.

For a detailed understanding of get_it and injectable , please refer to this awesome medium article by Rodrigo Martins

Using “get_it” & “injectable” package to configure dependencies in a multi-module project.

Feature Module:

// simple class from feature_module@Singleton()
Class Engine{
}
===========================// configure injectable in feature module@InjectableInit(
initializerName: r'$initModuleGetIt'
)
void configureModuleDependencies(GetIt getIt) => $initModuleGetIt(getIt);

Main Module:

// class from main module@Singleton()
class Vehicle {
final Engine engine;
Vehicle({this.engine});
}
========================// Configure injectable in main modulefinal getIt = GetIt.instance;
@InjectableInit(
initializerName: r'$initGetIt'
)
void configureDependencies() {
// configureDataDependencies imported from feature_module
configureDataDependencies(getIt);
$initGetIt(getIt);
}

Execute flutter packages pub run build_runner build in both, main directory and also in feature module directory to generate get_it configuration file by injectable.

injectable generated file for the feature module

injectable generated file for the main module

Now simply call configureDependencies() in your main func before running the App.

void main() {
configureDependencies();
runApp(MyApp());
}

Usage:

Vehicle vehicle = getIt.get();
OR
var vehicle = getIt.get<Vehicle>();
Photo by Ambreen Hasan on Unsplash

And That's it!! 🥳🥳🥳

Did I get something wrong? Mention it in the comments. I would love to improve. 😊