Dependency Injection with GetIt in Flutter: Setup Guide

Setting Up Dependency Injection (GetIt) in a Flutter App Setting up DI in a Flutter project often turns into chaos: dependencies are initialized in random places, code becomes untestable, and after architectural changes, the app crashes on startup. We solve this problem with **GetIt** — a simple

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Dependency Injection with GetIt in Flutter: Setup Guide
Simple
from 1 day to 3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Setting Up Dependency Injection (GetIt) in a Flutter App

Setting up DI in a Flutter project often turns into chaos: dependencies are initialized in random places, code becomes untestable, and after architectural changes, the app crashes on startup. We solve this problem with GetIt — a simple and reliable service locator we've used in over 30 commercial projects. Our experience shows: proper GetIt configuration reduces dependency debugging time by 3–5 times and makes the code ready for Clean Architecture. Budget savings on debugging can reach 40% — that's hundreds of hours or tens of thousands of rubles in developer salaries.

GetIt is a service locator for Dart/Flutter, the de facto standard for DI in projects where code generation isn't needed. According to the official documentation, it's the recommended approach for managing dependencies outside widgets. The principle is simple: register dependencies once at app startup, request them anywhere via GetIt.instance<T>() or the shorthand sl<T>(). We guarantee that after our setup, you'll forget about manual parameter passing through constructors.

Why GetIt Instead of Provider or Riverpod?

Provider and Riverpod are state management tools with DI as a side effect. GetIt is a pure service locator without Flutter dependencies: it can be used in the domain layer without BuildContext. For Clean Architecture, where the domain layer knows nothing about Flutter, this is crucial. Additionally, GetIt runs 2–3 times faster at app startup because it doesn't need to build a widget tree.

The GetIt constructor supports three registration modes:

  • registerSingleton<T> — creates immediately upon registration, lives for the entire app lifetime.
  • registerLazySingleton<T> — creates on first access, then returns the same instance.
  • registerFactory<T> — creates a new instance on every access.

We recommend using registerLazySingleton for most services (ApiService, DatabaseHelper) and registerFactory for short-lived objects (e.g., BLoCs created via GetIt).

How to Avoid the Typical Async Initialization Error?

// Wrong — synchronous registration of an async dependency sl.registerLazySingleton<DatabaseHelper>(() => DatabaseHelper()..init()); // Correct — async init via registerSingletonAsync sl.registerSingletonAsync<DatabaseHelper>(() async { final db = DatabaseHelper(); await db.init(); return db; }); // And wait for readiness before runApp: await sl.allReady(); 

If you don't use registerSingletonAsync + allReady(), DatabaseHelper may be requested before async initialization completes — a crash on startup with StateError: Singleton is not ready yet. In our projects, we always wrap DB and SharedPreferences initialization in this pattern.

Comparison of GetIt Registration Types

Type Creation Time Number of Instances When to Use
registerSingleton At registration 1 (one for the whole app) Configurations, loggers
registerLazySingleton On first access 1 ApiService, DatabaseHelper, repositories
registerFactory On every access Many Use Cases, BLoCs (if created via GetIt)

Steps to Set Up the DI System

Step Tasks Duration
Analysis and Design Identify 'leaky' dependencies, draw DI diagram 3–4 hours
Write injection_container Register all services, async initialization 1–2 days
Integration with feature modules Split by features for large projects 1–2 days
Testing and code review Unit tests for registrations, peer review 1 day

How to Build a Modular DI System for Large Projects?

On large projects, a single injection_container.dart becomes 500 lines. The solution: split by features. Each feature module registers its own dependencies via separate functions like initAuthDependencies(), initProfileDependencies() — called from the main initDependencies(). We switched to this approach after a project grew to 15 features — now DI takes 3–4 days to set up, but maintenance requires half the time.

Organizing injection_container.dart

Standard practice is one file injection_container.dart (or di/) with an initDependencies() function:

Future<void> initDependencies() async { // External final sharedPrefs = await SharedPreferences.getInstance(); sl.registerLazySingleton(() => sharedPrefs); sl.registerLazySingleton(() => http.Client()); // Data sources sl.registerLazySingleton<AuthRemoteDataSource>( () => AuthRemoteDataSourceImpl(sl()), ); // Repositories sl.registerLazySingleton<AuthRepository>( () => AuthRepositoryImpl(sl()), ); // Use cases sl.registerLazySingleton(() => LoginUseCase(sl())); // BLoCs — if created via GetIt sl.registerFactory(() => AuthBloc(loginUseCase: sl())); } 

Register dependencies in bottom-up order: first external dependencies, then data sources, repositories, use cases, and finally the presentation layer. This rule guarantees all dependencies are available when accessed.

What's Included in a Turnkey GetIt Setup

  • Analysis of current architecture and identification of 'leaky' dependencies (about 3–4 hours).
  • Design the DI layer: choose registration types for each component (2–3 hours).
  • Write injection_container with async initialization for DB, SharedPreferences, Firebase (1–2 days).
  • Integrate with feature modules (if the project is large) — additional 1–2 days.
  • Write unit tests to verify registrations (mock replacement in setUp).
  • Documentation on adding new dependencies (1 hour).

Process

  1. Analysis: meeting with the team, studying the current architecture (3–4 hours).
  2. Design: dependency diagram, determine lifetimes (2–3 hours).
  3. Implementation: write injection_container and tests (1–2 days).
  4. Code review and deployment (1 day).
  5. Knowledge transfer: documentation and a call (1 hour).

Timelines and Cost

Estimated timeline: 2 to 5 days depending on project size. Cost is calculated individually after a code audit. Debugging time for improper DI can account for up to 30% of team time — our setup pays for itself in the first month by reducing that time. Get a consultation — contact us and we'll offer the optimal solution. Order a turnkey GetIt setup — guaranteed results.