rs_iron 0.0.1
rs_iron: ^0.0.1 copied to clipboard
A Spring-like dependency injection framework for Dart with code generation for Flutter compatibility.
rs_iron #
rs_iron is a code-generation-first dependency injection package for Dart and Flutter, optimized for mobile app development.
It provides annotation-based registration, constructor-based dependency resolution, and Flutter-friendly APIs without relying on dart:mirrors.
Install #
Add to your pubspec:
dependencies:
rs_iron: ^latest_package
dev_dependencies:
build_runner: ^2.4.13
Import #
Use the new entry file:
import 'package:rs_iron/rs_iron.dart';
Quick Start #
1. Annotate your classes #
import 'package:rs_iron/rs_iron.dart';
@Repository()
class UserRepository {
Future<String> getUserName() async => 'Jane';
}
@Service()
class UserService {
final UserRepository repository;
UserService(this.repository);
Future<String> loadName() => repository.getUserName();
}
2. Add an entry point #
import 'package:rs_iron/rs_iron.dart';
@IronEntryPoint()
class AppModule {}
3. Generate #
dart run build_runner build
This creates a generated file next to your entry point, for example:
app_module.rs_iron.dart
4. Initialize and resolve #
import 'package:rs_iron/rs_iron.dart';
import 'app_module.rs_iron.dart';
Future<void> main() async {
final container = IronContainer();
await container.scan();
container.registerGeneratedDependencies();
final userService = container.get<UserService>();
print(await userService.loadName());
}
Flutter Usage #
Use IronCore for lifecycle/access helpers and IronMixin for generated shortcut properties.
import 'package:flutter/material.dart';
import 'package:rs_iron/rs_iron.dart';
import 'app_module.rs_iron.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await IronCore.initialize((container) {
container.registerGeneratedDependencies();
});
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => const MaterialApp(home: HomePage());
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with IronCore, IronMixin {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('rs_iron example')),
body: FutureBuilder<String>(
future: userService.loadName(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
return Center(child: Text(snapshot.data!));
},
),
);
}
}
Common Commands #
dart run build_runner build
dart run build_runner watch
dart run build_runner clean
Notes #
- Prefer constructor injection for better testability and compile-time safety.
- Singleton scope (default) - Use for services, repositories, and shared resources that persist throughout the app lifecycle. Initialized eagerly at startup.
- Lazy Singleton scope - Use for singletons that should only be instantiated when first requested, saving startup time and memory.
- Factory scope - Use for stateful widgets, view models, or when you need fresh instances for each injection.
- Re-run code generation after adding or renaming annotated classes.
- Keep one
@IronEntryPoint()annotation per app module.