depend 2.0.1 depend: ^2.0.1 copied to clipboard
Dependencies is a library for managing dependencies in Flutter applications. It provides a convenient way to initialize and access services or repositories via an InheritedWidget.
depend #
depend
is a library for managing dependencies in Flutter applications. It provides a convenient way to initialize and access services or repositories via an InheritedWidget
.
Why it Rocks 🚀 #
- Initialize dependencies before launching the app
- Access dependencies from anywhere in the widget tree
- Log initialization times for each dependency
- Clean and extensible way to manage dependencies
- Easy to use and integrate with existing codebases
Installation #
Add the package to your pubspec.yaml
:
dependencies:
depend: ^0.0.1
Then run:
$ flutter pub get
Example Usage #
Example 1: Define Dependencies #
Step 1: Extends DependenciesLibrary
Create a DependenciesLibrary
that extends DependenciesLibrary
and initializes your dependencies:
class RootLibrary extends DependenciesLibrary {
late final ApiService apiService;
@override
Future<void> init() async {
await log(() async => apiService = await ApiService().init());
}
}
Step 2: Initialize Dependencies
Use DependenciesInit
to initialize your dependencies before launching the app:
void main() {
runApp(
Dependencies<RootLibrary>(
library: RootLibrary(),
placeholder: const ColoredBox(
color: Colors.white,
child: Center(child: CircularProgressIndicator()),
),
child: const MyApp(),
),
);
}
Step 3: Access Dependencies with InheritedWidget
Once initialized, dependencies can be accessed from anywhere in the widget tree using Dependencies.of(context).authRepository
:
/// The repository for the example
final class AuthRepository {
final AuthDataSource dataSource;
AuthRepository({required this.dataSource});
Future<String> login() => dataSource.login();
void dispose() {
// stream.close();
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Dependencies<ModuleLibrary>(
library: ModuleLibrary(
parent: Dependencies.of<RootLibrary>(context),
),
child: BlocProvider(
create: (context) => DefaultBloc(
Dependencies.of<ModuleLibrary>(context).authRepository,
),
child: const MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _login() {
context.read<DefaultBloc>().add(DefaultEvent());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
BlocBuilder<DefaultBloc, DefaultState>(
builder: (context, state) {
return Text('Login: ${state.authorized}');
},
),
Builder(
builder: (context) {
return ElevatedButton(
onPressed: _login,
child: const Text('Login'),
);
},
)
],
),
),
),
);
}
}
Example 2: Use Parent Dependencies #
Step 1: Define Parent Dependencies
class RootLibrary extends DependenciesLibrary {
late final ApiService apiService;
@override
Future<void> init() async {
apiService = await ApiService().init();
}
}
class ModuleLibrary extends DependenciesLibrary<RootLibrary> {
late final AuthRepository authRepository;
ModuleLibrary({required super.parent});
@override
Future<void> init() async {
// initialize dependencies
authRepository = AuthRepository(
dataSource: AuthDataSource(
apiService: parent.apiService, // parent - RootLibrary
),
);
}
@override
void dispose() {
authRepository.dispose();
}
}
Logging and Debugging #
During initialization, each dependency logs the time it took to initialize:
class ModuleLibrary extends DependenciesLibrary<RootLibrary> {
late final AuthRepository authRepository;
ModuleLibrary({required super.parent});
@override
Future<void> init() async {
await log(() async => authRepository = AuthRepository(
dataSource: AuthDataSource(
apiService: parent.apiService,
),
),
);
}
}
💡 ApiService: initialized successfully for 10 ms
💡 AuthRepository: initialized successfully for 0 ms
This is useful for tracking performance and initialization times.