modugo 3.3.0 copy "modugo: ^3.3.0" to clipboard
modugo: ^3.3.0 copied to clipboard

Modular Routing and Dependency Injection for Flutter with GetIt and GoRouter.

example/modugo_example.dart

/// A complete example using Modugo for modular routing and dependency injection.
///
/// This example includes:
/// - A repository interface and its implementation
/// - A controller that depends on the repository
/// - A module that registers all dependencies and routes
/// - A basic UI that consumes the controller
///
/// To run this example, ensure Modugo is added as a dependency in your pubspec.yaml,
/// then use `flutter run example/modugo_example.dart`.
library;

import 'package:flutter/material.dart';

import 'package:modugo/modugo.dart';
// import 'package:shared_preferences/shared_preferences.dart';

Future<void> main() async {
  // Initialize Modugo with the root module
  WidgetsFlutterBinding.ensureInitialized();

  await Modugo.configure(
    module: AppModule(),
    initialRoute: '/',
    debugLogDiagnostics: true,
    errorBuilder: AppResolver.error,
    debugLogDiagnosticsGoRouter: true,
  );

  runApp(AppResolver.app);
}

/// Resolves the root application widget and manages asynchronous dependencies.
///
/// [AppResolver] provides a single point to access the main app widget (`app`),
/// handles error navigation (`error`), and exposes all async dependencies required
/// before rendering the app.
///
/// Usage:
/// ```dart
/// runApp(AppResolver.app);
/// ```
final class AppResolver {
  /// Returns the main application widget wrapped in [ModugoLoaderWidget].
  ///
  /// This ensures that all asynchronous dependencies are completed before
  /// building the app. While waiting, the `loading` widget is displayed.
  ///
  /// Example:
  /// ```dart
  /// Widget mainApp = AppResolver.app;
  /// runApp(mainApp);
  /// ```
  static Widget get app => ModugoLoaderWidget(
    loading: const Placeholder(), // Displayed while dependencies load
    dependencies: _dependencies(),
    builder: (_) => const AppWidget(),
  );

  /// Handles navigation when an error occurs during route resolution.
  ///
  /// Typically redirects the user to a safe route (e.g., '/').
  ///
  /// Parameters:
  /// - [context]: The current [BuildContext]
  /// - [state]: The [GoRouterState] containing routing information
  ///
  /// Returns a widget to display (can be `SizedBox.shrink()` if redirection occurs).
  static Widget error(BuildContext context, GoRouterState state) {
    context.go('/');
    return const Placeholder();
  }

  /// Returns a list of asynchronous dependencies to be awaited before
  /// building the app.
  ///
  /// This method allows dynamically composing the list of futures that need
  /// to be resolved, including:
  /// - Any singleton async registrations from GetIt/Modugo
  /// - Service initializations (e.g., SharedPreferences, Firebase, RemoteConfig)
  ///
  /// The returned `Future<List<Future<void>>>` ensures that [ModugoLoaderWidget]
  /// can await all necessary initializations.
  ///
  /// Example usage inside the loader:
  /// ```dart
  /// ModugoLoaderWidget(
  ///   loading: CircularProgressIndicator(),
  ///   dependencies: AppResolver._dependencies(),
  ///   builder: (_) => const AppWidget(),
  /// );
  /// ```
  static Future<void> _dependencies() async {
    // Example using SharedPreferences
    // await Modugo.i.isReady<SharedPreferences>();

    // Example: wait for all required async services
    await Future.wait([
      Modugo.i.allReady(), // Ensure all GetIt singletons are ready
      // Add other async dependencies here.
    ]);
  }
}

/// The root widget for the app.
final class AppWidget extends StatelessWidget {
  const AppWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Modugo App',
      routerConfig: Modugo.routerConfig,
    );
  }
}

/// The root module that defines app-level routes.
///
/// This module includes [HomeModule] as its child.
final class AppModule extends Module {
  @override
  List<IRoute> routes() => [ModuleRoute(path: '/', module: HomeModule())];
}

/// The home module that handles feature-specific dependencies and routes.
final class HomeModule extends Module {
  @override
  void binds() {
    // Example using SharedPreferences
    // i.registerSingletonAsync<SharedPreferences>(
    //   () async => await SharedPreferences.getInstance(),
    // );

    i
      ..registerSingleton<ModugoRepository>(ModugoRepositoryImpl())
      ..registerLazySingleton<HomeController>(
        () => HomeController(i.get<DateTime>(), i.get<ModugoRepository>()),
      )
      ..registerFactory<DateTime>(() => DateTime.now());
  }

  @override
  List<IRoute> routes() => [
    ChildRoute(
      path: '/',
      name: 'home-route',
      child: (context, _) {
        final controller = context.read<HomeController>();
        return HomeScreen(controller: controller);
      },
    ),
  ];
}

/// UI screen that displays a message from the controller.
final class HomeScreen extends StatelessWidget {
  final HomeController _controller;

  const HomeScreen({super.key, required HomeController controller})
    : _controller = controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Modugo Example')),
      body: Center(child: Text(_controller.message())),
    );
  }
}

/// Controller that consumes [ModugoRepository] to provide business logic.
final class HomeController {
  final DateTime date;
  final ModugoRepository repository;

  HomeController(this.date, this.repository);

  String message() =>
      '${repository.welcome()}\n${date.weekday}-${date.month}-${date.year}';
}

/// Abstract contract for a data repository.
abstract interface class ModugoRepository {
  String welcome();
}

/// Concrete implementation of [ModugoRepository].
final class ModugoRepositoryImpl implements ModugoRepository {
  @override
  String welcome() => 'Welcome!';
}
11
likes
160
points
1.12k
downloads
screenshot

Publisher

unverified uploader

Weekly Downloads

Modular Routing and Dependency Injection for Flutter with GetIt and GoRouter.

Repository (GitHub)
View/report issues

Topics

#modugo #routing #injection #navigation #deep-linking

Documentation

API reference

License

MIT (license)

Dependencies

event_bus, flutter, get_it, go_router, talker_logger

More

Packages that depend on modugo