depend 2.0.1  depend: ^2.0.1 copied to clipboard
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.