Skip to main content

Dependency Injection

Zuraffa provides an automated, modular dependency injection setup using GetIt. By using the --di flag, Zuraffa generates and maintains registration files for your repositories, data sources, and services.


πŸ¦„ Architecture​

Zuraffa's DI follows a "Lazy Singleton" approach by default, ensuring components are only instantiated when needed. The structure is split into domain-specific registration files to prevent circular dependencies and merge conflicts.

lib/src/di/
β”œβ”€β”€ datasources/
β”‚ β”œβ”€β”€ product_remote_datasource_di.dart
β”‚ └── product_local_datasource_di.dart
β”œβ”€β”€ repositories/
β”‚ └── product_repository_di.dart
β”œβ”€β”€ index.dart # Root registration entry point
└── service_locator.dart # The GetIt instance

πŸš€ Basic Usage​

1. Generate with DI​

When generating a feature, include the --di flag:

zfa feature Product --data --di

2. Initialize in main.dart​

Import the generated index.dart and call setupDependencies() before runApp():

import 'package:get_it/get_it.dart';
import 'src/di/index.dart';

final getIt = GetIt.instance;

void main() async {
WidgetsFlutterBinding.ensureInitialized();

// Register all Zuraffa dependencies
await setupDependencies(getIt);

runApp(MyApp());
}

πŸ§ͺ Development with Mocks​

Zuraffa makes it easy to swap real implementations for mocks during development or testing.

Swapping at Registration​

Use the --use-mock flag to register a MockDataSource instead of the RemoteDataSource:

zfa feature Product --data --mock --di --use-mock

Manual Swapping​

You can also conditionally register dependencies based on your environment:

Future<void> setupDependencies(GetIt getIt) async {
if (kDebugMode) {
await registerProductMockDataSource(getIt);
} else {
await registerProductRemoteDataSource(getIt);
}

await registerProductRepository(getIt);
}

🧠 Smart Registration​

Zuraffa's DI generator is "smart"β€”it understands your architectural choices:

  • Caching: If --cache is used, the DI registration will automatically wire the RemoteDataSource, LocalDataSource, and CachePolicy into the CachedRepository.
  • Services: If you use the --service pattern, Zuraffa generates a separate registration for the service interface and its implementation.
  • Custom View Preservation: Presentation layer components (View, Presenter, Controller) are not registered in the global DI container. Instead, they are instantiated within the View's state to ensure proper lifecycle management and cleanup.

πŸ“‚ Next Steps​