[Flutter] Dependency Management in Flutter: Using get_it with MobX and Provider

birdgang
4 min readSep 27, 2024

--

We’ll dive into the get_it package in Flutter, a popular package for handling dependency injection. We’ll explore how it works and how it integrates with two of the most well-known state management packages: MobX and Provider. I’ll walk you through each package, explain their internal structures and properties, and provide practical code examples.

1. What is the get_it package?

1.1 Introduction to get_it

get_it is a simple service locator for Flutter that allows you to manage objects globally and handle dependency injection (DI) easily. It works hand-in-hand with the Singleton pattern to provide easy access to services and objects throughout your app without tightly coupling them together.

1.2 Why use get_it?

  1. Dependency Injection : It decouples the creation of objects from their usage, making your code easier to maintain and test.
  2. Global Object Management : Allows for convenient access to global objects throughout the app.
  3. Simple Setup : The package is lightweight and straightforward to use for object registration and access.

2. Installing and Using get_it

2.1 Installing get_it

Add get_it to your `pubspec.yaml` file:

dependencies:
flutter:
sdk: flutter
get_it: ^7.2.0 # Update to the latest version

2.2 Basic Usage

To use get_it, follow these basic steps:

1. Register objects or services.
2. Access and use the registered objects in different parts of your app.

Step 1: Registering Services

import 'package:get_it/get_it.dart';

// Create an instance of GetIt
final getIt = GetIt.instance;

class MyService {
String fetchData() => "Data from MyService";
}

// Register services in the setup method
void setupServiceLocator() {
getIt.registerSingleton<MyService>(MyService());
}

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

Step 2: Accessing Services

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

class HomePage extends StatelessWidget {
final myService = GetIt.instance<MyService>();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('get_it Example')),
body: Center(
child: ElevatedButton(
onPressed: () {
final data = myService.fetchData();
print(data); // Outputs "Data from MyService"
},
child: Text('Fetch Data'),
),
),
);
}
}

With the above code, you’ve registered `MyService` globally, and you can now access it anywhere in your app.

3. Popular Packages to Use with get_it

While get_it is great for managing global objects, it’s even more powerful when combined with a state management solution. Two popular options in the Flutter ecosystem are MobX and Provider.

4. Using MobX with get_it

4.1 What is MobX?

MobX is a reactive state management library that allows for automatic updates to the UI when the state changes. It uses @observable, @action, and @computed decorators to make the state easily trackable and modifiable.

4.2 Installing MobX

To use MobX, add the following dependencies to your `pubspec.yaml`:

dependencies:
mobx: ^2.0.0
flutter_mobx: ^2.0.0
get_it: ^7.2.0

dev_dependencies:
build_runner: ^2.0.0
mobx_codegen: ^2.0.0 # For code generation

4.3 Writing a MobX Store

A Store in MobX contains the state of your application. Let’s create a simple counter store.

Step 1: Creating a Store

import 'package:mobx/mobx.dart';

part 'counter_store.g.dart'; // Generated file link

class CounterStore = _CounterStore with _$CounterStore;

abstract class _CounterStore with Store {
@observable
int counter = 0;

@action
void increment() {
counter++;
}

@computed
bool get isEven => counter % 2 == 0; // Check if the counter is even
}
  • @observable : Tracks the state of the variable.
  • @action : Defines methods that modify the state.
  • @computed : Returns a derived value based on observable state.

Run the following command to generate the `counter_store.g.dart` file:

flutter pub run build_runner build

Step 2: Register the MobX Store with get_it

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

final getIt = GetIt.instance;

void setupServiceLocator() {
getIt.registerSingleton<CounterStore>(CounterStore());
}

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

Step 3: Using MobX and get_it in the UI

import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:get_it/get_it.dart';
import 'counter_store.dart';

class HomePage extends StatelessWidget {
final counterStore = GetIt.instance<CounterStore>();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('MobX + get_it Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Observer(
builder: (_) => Text(
'Counter: ${counterStore.counter}',
style: TextStyle(fontSize: 24),
),
),
Observer(
builder: (_) => Text(
counterStore.isEven ? 'Even' : 'Odd',
style: TextStyle(fontSize: 24),
),
),
ElevatedButton(
onPressed: counterStore.increment,
child: Text('Increment'),
),
],
),
),
);
}
}
  • Observer : A widget that automatically updates when an observable state changes.

5. Using Provider with get_it

5.1 What is Provider?

Provider is one of the most widely-used state management solutions in Flutter. It uses InheritedWidget under the hood to efficiently propagate changes throughout the widget tree. When combined with `get_it`, it becomes easy to manage global services and state.

5.2 Installing Provider

dependencies:
flutter:
sdk: flutter
provider: ^6.0.0
get_it: ^7.2.0

5.3 Using get_it and Provider Together

Step 1: Register the Service with get_it

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

final getIt = GetIt.instance;

void setupServiceLocator() {
getIt.registerSingleton<MyService>(MyService());
}

void main() {
setupServiceLocator();
runApp(
MultiProvider(
providers: [
Provider<MyService>(create: (_) => GetIt.instance<MyService>()),
],
child: MyApp(),
),
);
}

Step 2: Accessing the Service with Provider

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'my_service.dart';

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final myService = Provider.of<MyService>(context);

return Scaffold(
appBar: AppBar(title: Text('Provider + get_it Example')),
body: Center(
child: ElevatedButton(
onPressed: () {
final data = myService.fetchData();
print(data); // Outputs "Data from MyService"
},
child: Text('Fetch Data'),
),
),
);
}
}

6. MobX vs. Provider : When to Use Which?

  • MobX is great for reactive programming enthusiasts. It allows state changes to be automatically reflected in the UI, making the code concise and expressive.
  • Provider is perfect for simpler apps or developers who prefer a more declarative state management approach. It’s easy to use and integrates well with Flutter’s ecosystem.

7. Conclusion

The get_it package allows you to manage dependencies globally in a Flutter app, making your code more modular and testable. Combining get_it with state management solutions like MobX and Provider makes it even more powerful. Both MobX and Provider have their strengths, and the best choice depends on your app’s complexity and your preferred development style.

--

--