get_it_lazyload 0.0.3
get_it_lazyload: ^0.0.3 copied to clipboard
A Flutter package providing optimized lazy loading extensions for GetIt dependency injection with comprehensive support for all registration types and async dependencies.
get_it_lazyload #
A Flutter package providing optimized lazy loading extensions for GetIt dependency injection with comprehensive support for all registration types and async dependencies.
โจ Features #
- ๐ Optimized Lazy Loading: Efficient dependency registration with automatic instance creation
- ๐ Multiple Registration Types: Support for factory, singleton, and lazy singleton patterns
- โก Async Support: Full support for asynchronous dependency initialization
- ๐ฏ Performance Optimized: Minimal overhead with smart registration checking
- ๐ก๏ธ Type Safe: Full type safety with generic methods
- ๐งช Well Tested: 100% test coverage ensuring reliability
๐ฆ Installation #
Add this to your package's pubspec.yaml file:
dependencies:
get_it_lazyload: ^0.0.3
get_it: ^8.2.0
Then run:
flutter pub get
๐ Quick Start #
import 'package:get_it/get_it.dart';
import 'package:get_it_lazyload/get_it_lazyload.dart';
final getIt = GetIt.instance;
// Register a service with automatic lazy loading
final service = getIt.getOrRegister<MyService>(
() => MyService(),
RegisterAs.singleton
);
๐ Usage #
Basic Usage #
import 'package:get_it/get_it.dart';
import 'package:get_it_lazyload/get_it_lazyload.dart';
final getIt = GetIt.instance;
// Register a service with automatic lazy loading
getIt.getOrRegister<MyService>(() => MyService(), RegisterAs.singleton);
// Get the service (will be created if not registered)
final service = getIt.get<MyService>();
Lazy Loading Pattern for Use Cases and Repositories #
The main benefit of this package is avoiding eager registration of dependencies at app startup. Instead, dependencies are loaded and registered only when they're actually required:
// UseCase with Factory pattern (creates new instance each time)
class AnonymousAuthUseCase {
final AuthRepository _repository;
AnonymousAuthUseCase(this._repository);
Future<FirebaseUserModel> execute() {
return _repository.signInAnonymously();
}
static AnonymousAuthUseCase get() {
return GetIt.instance.getOrRegister<AnonymousAuthUseCase>(
() => AnonymousAuthUseCase(AuthRepository.get()),
RegisterAs.factory);
}
}
// Repository with LazySingleton pattern (reuses instance)
class AuthRepository {
final DatabaseService _database;
AuthRepository(this._database);
Future<FirebaseUserModel> signInAnonymously() async {
return _database.createAnonymousUser();
}
static AuthRepository get() {
return GetIt.instance.getOrRegister<AuthRepository>(
() => AuthRepository(DatabaseService.get()),
RegisterAs.lazySingleton);
}
}
// Service with Singleton pattern (created immediately when first accessed)
class DatabaseService {
static DatabaseService get() {
return GetIt.instance.getOrRegister<DatabaseService>(
() => DatabaseService(),
RegisterAs.singleton);
}
}
Benefits of this pattern:
- โ Dependencies are created only when needed
- โ No eager registration at app startup
- โ Automatic dependency resolution
- โ Clean separation of concerns
- โ Easy to test and mock
Registration Types #
Singleton
Creates instance immediately and reuses it:
getIt.getOrRegister<ConfigService>(
() => ConfigService(),
RegisterAs.singleton
);
Factory
Creates new instance each time:
getIt.getOrRegister<DataModel>(
() => DataModel(),
RegisterAs.factory
);
Lazy Singleton
Creates instance on first use, then reuses it:
getIt.getOrRegister<ExpensiveService>(
() => ExpensiveService(),
RegisterAs.lazySingleton
);
Async Dependencies #
Async Factory
final service = await getIt.getOrRegisterAsync<AsyncService>(
() async => await AsyncService.initialize(),
RegisterAs.factoryAsync
);
Async Lazy Singleton
final service = await getIt.getOrRegisterAsync<AsyncService>(
() async => await AsyncService.initialize(),
RegisterAs.lazySingletonAsync
);
Async Singleton
final service = await getIt.getOrRegisterAsync<AsyncService>(
() async => await AsyncService.initialize(),
RegisterAs.singletonAsync
);
Convenience Methods #
For common use cases, you can use these convenience methods:
// Factory registration
getIt.getOrRegisterFactory<DataModel>(() => DataModel());
// Lazy singleton registration
getIt.getOrRegisterLazySingleton<Service>(() => Service());
// Singleton registration
getIt.getOrRegisterSingleton<Config>(() => Config());
// Async variants
await getIt.getOrRegisterFactoryAsync<AsyncService>(
() async => await AsyncService.initialize()
);
await getIt.getOrRegisterLazySingletonAsync<AsyncService>(
() async => await AsyncService.initialize()
);
await getIt.getOrRegisterSingletonAsync<AsyncService>(
() async => await AsyncService.initialize()
);
๐ API Reference #
RegisterAs Enum #
RegisterAs.singleton- Creates instance immediately and reuses itRegisterAs.factory- Creates new instance each timeRegisterAs.lazySingleton- Creates instance on first use, then reuses itRegisterAs.factoryAsync- Creates new async instance each timeRegisterAs.lazySingletonAsync- Creates async instance on first use, then reuses itRegisterAs.singletonAsync- Creates async instance immediately and reuses it
GetItExtension Methods #
getOrRegister<T>()- Gets or registers a dependencygetOrRegisterAsync<T>()- Gets or registers an async dependencygetOrRegisterFactory<T>()- Gets or registers as factorygetOrRegisterLazySingleton<T>()- Gets or registers as lazy singletongetOrRegisterSingleton<T>()- Gets or registers as singletongetOrRegisterFactoryAsync<T>()- Gets or registers as async factorygetOrRegisterLazySingletonAsync<T>()- Gets or registers as async lazy singletongetOrRegisterSingletonAsync<T>()- Gets or registers as async singleton
๐ Performance Benefits #
- Single Registration Check: Only checks if dependency is registered once per call
- Optimized Registration: Direct function registration without extra wrapping
- Lazy Initialization: Dependencies are only created when needed
- Memory Efficient: Reuses instances where appropriate
- Startup Performance: No eager registration means faster app startup
โ ๏ธ Important Notes #
Async Registration Behavior #
Due to GetIt's internal implementation of async registrations, there are some limitations to be aware of:
- Async Factory: Works as expected - creates new instances each time
- Async Lazy Singleton: May create new instances on subsequent calls due to GetIt's async registration behavior
- Async Singleton: Works as expected - creates instance once and reuses it
For the most reliable behavior with async dependencies, consider using RegisterAs.singletonAsync when you need consistent instance reuse.
Best Practices #
- Use sync registration methods when possible for better performance
- Reserve async registration for dependencies that truly require async initialization
- Test your dependency injection setup thoroughly, especially with async services
- Consider using
RegisterAs.singletonAsyncfor services that should be shared across your app - Use the lazy loading pattern for UseCases and Repositories to avoid eager registration
- Only register core dependencies (like config) at app startup
๐ฑ Example #
Check out the example app for a complete working demonstration of the lazy loading pattern.
import 'package:get_it/get_it.dart';
import 'package:get_it_lazyload/get_it_lazyload.dart';
class MyApp {
static void setupDependencies() {
final getIt = GetIt.instance;
// Only register core dependencies that are needed immediately
getIt.getOrRegister<ConfigService>(
() => ConfigService(),
RegisterAs.singleton
);
// Other dependencies will be registered lazily when first accessed
// No need to register AuthRepository, AnonymousAuthUseCase, etc. here
}
}
๐งช Testing #
The package includes comprehensive tests with 100% coverage:
# Run tests
flutter test
# Run tests with coverage
flutter test --coverage
๐ค Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
- Built on top of the excellent GetIt package
- Inspired by clean architecture principles and dependency injection best practices
- Community feedback and contributions
๐ Package Health #
- โ Test Coverage: 100%
- โ Static Analysis: Passing
- โ Documentation: Complete
- โ Examples: Included
- โ License: MIT
- โ Platform Support: Flutter (iOS, Android, Web, Desktop)