Keyboard Shortcuts

j / kScroll down / up
ggScroll to top
GScroll to bottom
K / /Open search
?Show this help
EscClose search / help
n / NNext / previous section
hGo to landing
dGo to docs
:Command mode — type section name

Press ? or Esc to close

Architecture

Dependency Injection

Core services registered once at bootstrap. Feature DI registered at bootstrap, scoped by lazy singletons and factories.

Bootstrap — Core Services

lib/app/app_bootstrap.dart
final sl = GetIt.instance;

Future<void> bootstrap() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Singletons — one instance, shared across app
  sl.registerSingleton<SharedPreferences>(await SharedPreferences.getInstance());
  sl.registerSingleton<Logger>(initLogger());
  sl.registerSingleton<FlutterSecureStorage>(const FlutterSecureStorage());
  sl.registerSingleton<ApiClient>(ApiClient());

  // Lazy singletons — created on first access
  sl.registerLazySingleton(() => GlobalErrorCubit());
  sl.registerLazySingleton(() => ThemeCubit(sl()));
  sl.registerLazySingleton(() => LocalizationCubit(...));
  sl.registerLazySingleton(() => ConnectivityCubit(Connectivity()));

  // Feature DI — registered at bootstrap, lazy-loaded
  registerAuthDependencies();
  registerProfileDependencies();
  registerHomeDependencies();
  // ... all features
}

Feature DI — Lazy Singletons + Factories

lib/features/profile/config/profile_di.dart
void registerProfileDependencies() {
  // Lazy singleton — one instance per app lifecycle
  sl.registerLazySingleton(() => ProfileDataSource(sl<ApiClient>()));
  sl.registerLazySingleton(() => ProfileStore(sl<ProfileDataSource>()));

  // Factory — new instance each time
  sl.registerFactory(() => ProfileCubit(sl<ProfileStore>()));
  sl.registerFactory(() => FollowCubit(sl<FollowStore>()));
}

Usage in Cubit

lib/features/profile/logic/profile_cubit.dart
class ProfileCubit extends Cubit<ProfileState> {
  final ProfileStore _store;

  ProfileCubit(this._store) : super(ProfileState.initial());

  Future<void> fetchMyProfile() async {
    emit(state.copyWith(userProfileResponse: state.userProfileResponse.loading));
    final result = await _store.getMyProfile();
    emit(state.copyWith(userProfileResponse: result));
  }
}

Registration Rules

TypeRegistrationScope
Core servicesregisterSingletonOne instance, app-wide
Feature storesregisterLazySingletonOne instance, created on first access
Feature cubitsregisterFactoryNew instance per BlocProvider
Data sourcesregisterLazySingletonOne instance, shared by stores
sam's arch — A Pragmatic Flutter Architecture