Dependency injection helps you organize your app by giving parts what they need without making them find it themselves. GetIt is a simple tool to do this in Flutter.
When you want to share a single object, like a service, across many parts of your app.
When you want to make your code easier to test by swapping real objects with fake ones.
When you want to avoid creating the same object multiple times.
When you want to keep your widgets clean and not worry about how to create dependencies.
When you want a simple way to manage app-wide objects without complex setup.
Syntax
Flutter
final getIt = GetIt.instance;
// Register a singleton
getIt.registerSingleton<MyService>(MyService());
// Access the registered service
var service = getIt<MyService>();
Use registerSingleton to create one shared instance.
Use getIt() to get the instance anywhere in your app.
Examples
This example shows how to register and get a simple service that counts.
Flutter
final getIt = GetIt.instance;
// Register a singleton service
getIt.registerSingleton<CounterService>(CounterService());
// Later, get the service
var counter = getIt<CounterService>();
Using registerFactory creates a new object every time you ask for it.
Flutter
final getIt = GetIt.instance;
// Register a factory to create a new instance each time
getIt.registerFactory<Logger>(() => Logger());
// Get a new Logger instance
var logger1 = getIt<Logger>();
var logger2 = getIt<Logger>();
Sample App
This Flutter app uses GetIt to share a CounterService across widgets. The count updates when you press the button.
Flutter
import'package:flutter/material.dart';
import'package:get_it/get_it.dart';
// Simple service that holds a countclass CounterService {
int count = 0;
void increment() {
count++;
}
}
final getIt = GetIt.instance;
void main() {
// Register the CounterService as a singleton
getIt.registerSingleton<CounterService>(CounterService());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}
class CounterScreen extends StatefulWidget {
@override
State<CounterScreen> createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
// Get the service instancefinal counterService = getIt<CounterService>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('GetIt Dependency Injection')),
body: Center(
child: Text('Count: ${counterService.count}', style: TextStyle(fontSize: 24)),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
counterService.increment();
});
},
child: Icon(Icons.add),
tooltip: 'Increment count',
),
);
}
}
OutputSuccess
Important Notes
Remember to register your services before running the app.
Singletons keep the same instance, factories create new ones each time.
GetIt helps keep your widgets simple and focused on UI.
Summary
Dependency injection gives parts of your app what they need without making them create it.
GetIt is an easy tool to register and get shared objects in Flutter.
Use singletons for shared objects and factories for new instances.
Practice
(1/5)
1. What is the main purpose of using GetIt in a Flutter app?
easy
A. To handle user input events
B. To style widgets with custom themes
C. To manage app navigation between screens
D. To provide shared objects to parts of the app without creating them each time
Solution
Step 1: Understand Dependency Injection
Dependency injection means giving parts of your app the objects they need without making them create those objects themselves.
Step 2: Role of GetIt
GetIt is a tool that helps register and provide these shared objects easily in Flutter.
Final Answer:
To provide shared objects to parts of the app without creating them each time -> Option D
Quick Check:
Dependency injection = shared objects without recreation [OK]
Hint: GetIt shares objects so you don't recreate them [OK]
Common Mistakes:
Confusing GetIt with UI styling tools
Thinking GetIt manages navigation
Assuming GetIt handles user input
2. Which of the following is the correct way to register a singleton instance with GetIt?
easy
A. GetIt.instance.registerSingleton(() => MyService());
B. GetIt.instance.registerSingleton(MyService());
C. GetIt.instance.registerFactory(() => MyService());
D. GetIt.instance.registerLazySingleton(MyService());
Solution
Step 1: Understand Singleton Registration Syntax
To register a singleton, you pass an instance directly, not a function.
Step 2: Analyze Options
GetIt.instance.registerSingleton(MyService()); correctly passes an instance: MyService(). GetIt.instance.registerSingleton(() => MyService()); wrongly passes a function. GetIt.instance.registerFactory(() => MyService()); registers a factory, not a singleton. GetIt.instance.registerLazySingleton(MyService()); passes an instance to lazy singleton incorrectly.
Final Answer:
GetIt.instance.registerSingleton(MyService()); -> Option B
Quick Check:
Singleton registration needs instance, not function [OK]
Hint: Singletons get instances, factories get functions [OK]
Common Mistakes:
Passing a function instead of an instance for singleton
Confusing registerFactory with registerSingleton
Using wrong syntax for lazy singleton
3. Given the code below, what will be printed?
final getIt = GetIt.instance;
class Counter {
int value = 0;
void increment() => value++;
}
void main() {
getIt.registerSingleton(Counter());
final counter1 = getIt<Counter>();
final counter2 = getIt<Counter>();
counter1.increment();
print(counter2.value);
}
medium
A. 1
B. null
C. 0
D. Throws an error
Solution
Step 1: Understand Singleton Behavior
Registering Counter as a singleton means counter1 and counter2 point to the same instance.
Step 2: Trace the Code Execution
Calling counter1.increment() increases value from 0 to 1. Since counter2 is the same instance, counter2.value is 1.
Final Answer:
1 -> Option A
Quick Check:
Singleton shares state, so value = 1 [OK]
Hint: Singleton means one shared instance, so changes reflect everywhere [OK]
Common Mistakes:
Thinking counter2 is a new instance with value 0
Assuming increment does not affect shared instance
Expecting null or error without registration
4. What is wrong with this GetIt registration code?
final getIt = GetIt.instance;
void setup() {
getIt.registerFactory<MyService>(MyService());
}
medium
A. registerFactory expects a function, not an instance
B. registerFactory cannot be called inside a function
C. MyService must be a singleton, not a factory
D. GetIt.instance should not be assigned to a variable
Solution
Step 1: Check registerFactory Syntax
The registerFactory method expects a function that returns a new instance each time, not an instance itself.
Step 2: Identify the Error
Passing MyService() directly is an instance, not a function. The correct usage is registerFactory(() => MyService()).
Final Answer:
registerFactory expects a function, not an instance -> Option A
Quick Check:
Factories need functions returning new instances [OK]
Hint: Factories need functions, singletons need instances [OK]
Common Mistakes:
Passing instance instead of function to registerFactory
Thinking registerFactory only works outside functions
Confusing singleton and factory registration
5. You want to register a service that should create a new instance every time it is requested. Which GetIt method should you use, and how should you register it?
hard
A. Use registerLazySingleton with a function returning a new instance
B. Use registerSingleton with an instance of the service
C. Use registerFactory with a function returning a new instance
D. Use registerSingleton with a function returning a new instance
Solution
Step 1: Understand the Requirement
The service must create a new instance every time it is requested, so it should not be a singleton.
Step 2: Choose Correct GetIt Method
registerFactory registers a function that returns a new instance on each call, matching the requirement.
Step 3: Confirm Registration Syntax
The correct syntax is registerFactory(() => Service()), passing a function that creates a new instance.
Final Answer:
Use registerFactory with a function returning a new instance -> Option C
Quick Check:
New instance each time = registerFactory with function [OK]
Hint: New instance each time? Use registerFactory with a function [OK]
Common Mistakes:
Using registerSingleton for new instances
Passing instance instead of function to registerFactory
Confusing lazy singleton with factory
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.