The service locator pattern helps you find and use services or objects easily in your app without passing them everywhere. It keeps your code clean and simple.
Service locator pattern in Flutter
final locator = GetIt.instance; // Register a service locator.registerLazySingleton<Service>(() => ServiceImplementation()); // Use the service final service = locator<Service>();
Use registerLazySingleton to create the service only when needed.
Use locator to get the registered service anywhere in your code.
final locator = GetIt.instance; // Register a service locator.registerSingleton<Logger>(Logger()); // Access the service final logger = locator<Logger>(); logger.log('App started');
final locator = GetIt.instance; // Register a service lazily locator.registerLazySingleton<ApiService>(() => ApiServiceImpl()); // Later in the code final api = locator<ApiService>(); api.fetchData();
This test shows how the service locator provides the same CounterService instance everywhere. Incrementing count from one reference affects the other.
import 'package:get_it/get_it.dart'; class CounterService { int count = 0; void increment() => count++; } void main() { final locator = GetIt.instance; // Register the CounterService locator.registerLazySingleton<CounterService>(() => CounterService()); // Get the service and use it final counter1 = locator<CounterService>(); counter1.increment(); counter1.increment(); // Get the service again final counter2 = locator<CounterService>(); print('Counter1 count: ${counter1.count}'); print('Counter2 count: ${counter2.count}'); // Check if both are the same instance print('Same instance: ${identical(counter1, counter2)}'); }
Always register services before using them to avoid errors.
Use service locator carefully to avoid hiding dependencies, which can make testing harder.
For testing, you can replace services in the locator with mock versions easily.
The service locator pattern helps manage and access shared services easily.
It reduces the need to pass objects through many layers.
It supports better testing by allowing easy swapping of services.
Practice
Service Locator Pattern in Flutter testing?Solution
Step 1: Understand the role of service locator
The service locator pattern provides a central place to get instances of services needed across the app.Step 2: Compare with other options
Creating UI widgets, handling input, and managing navigation are unrelated to service locator's purpose.Final Answer:
To provide a centralized way to access shared services without passing them manually -> Option CQuick Check:
Service locator = centralized service access [OK]
- Confusing service locator with UI widget creation
- Thinking it manages navigation or input events
- Assuming it replaces dependency injection completely
GetIt service locator in Flutter?Solution
Step 1: Recall GetIt registration syntax
GetIt usesregisterSingleton<T>(instance)to register a singleton service.Step 2: Check each option
GetIt.instance.registerSingleton<MyService>(MyService()); matches the correct syntax. Options A, B, and C use invalid or non-existent methods.Final Answer:
GetIt.instance.registerSingleton<MyService>(MyService()); -> Option BQuick Check:
Register singleton with registerSingleton() [OK]
- Using non-existent methods like addService or create
- Omitting the instance when registering
- Confusing registerSingleton with registerFactory
print(service.getData());?
class MyService {
String getData() => "Hello from Service";
}
final getIt = GetIt.instance;
void main() {
getIt.registerSingleton<MyService>(MyService());
var service = getIt<MyService>();
print(service.getData());
}Solution
Step 1: Understand service registration and retrieval
The serviceMyServiceis registered as a singleton and then retrieved correctly.Step 2: Analyze the method call
CallinggetData()returns the string "Hello from Service" as defined.Final Answer:
Hello from Service -> Option DQuick Check:
Registered service returns expected string [OK]
- Assuming print shows the instance reference
- Forgetting to register the service before use
- Expecting null if service is registered
final getIt = GetIt.instance;
void setup() {
getIt.registerSingleton<MyService>(MyService());
}
void main() {
setup();
getIt.registerSingleton<MyService>(MyService());
}Solution
Step 1: Review service registration calls
The serviceMyServiceis registered twice without unregistering first.Step 2: Understand GetIt behavior on duplicate registration
GetIt throws an exception if the same service is registered twice without reset or unregister.Final Answer:
Registering the same service twice causes an exception -> Option AQuick Check:
Duplicate registration = exception [OK]
- Assuming async await is needed for registration
- Thinking service instance creation is faulty
- Believing GetIt needs explicit initialization
Solution
Step 1: Understand service swapping in tests
To replace a service with a mock, you must unregister the original service first.Step 2: Register the mock service before test execution
Registering the mock after unregistering ensures the locator returns the mock during tests.Final Answer:
Unregister the real service, then register the mock service before the test runs -> Option AQuick Check:
Unregister real, register mock = swap services [OK]
- Registering both real and mock services for same type
- Not unregistering real service before mock
- Ignoring service locator and creating instances manually
Ready to prove it?
Pass the test and this pattern moves unknown
