go_router_modular 5.1.0+3
go_router_modular: ^5.1.0+3 copied to clipboard
Modular Routing and Dependency Injection for Flutter with GoRouter. Features event-driven architecture for seamless module communication and micro-frontend support.
5.1.0 #
Added #
- Stateful shell branch transitions:
StatefulShellBranchTransitionshelpers (e.g.withGoTransition, fade presets) so bottom tabs/branches can reuse the same transition style as modularGoRoutes.
Improved #
- Dependency injection — batch registration: Typed binds (
Bind<T>) are now indexed up front inregisterBatch, so any bind in the same batch can resolve siblings in any declaration order.commitBatchruns in three phases: materialize singletons, propagate cached instances to duplicateBindobjects, then fall back to deferred resolution forBind<Object>registrations. - Dependency injection — code quality: Extracted
_writeToCanonicalSlotto centralise the dual-map invariant (bindsMapfor unkeyed,bindsMapByKeyfor keyed binds). Replaced the ambiguousbool _handleExistingBindwith a_SlotConflictResolutionenum. Renamed_pendingBatchto_uncommittedBatch. Swallowed registration errors now surface viadart:developer.logwhendebugLogGoRouterModularis enabled.
Fixed #
- Singleton identity across interface lookups:
BindLocator._searchCompatibleBindnow reuses the canonical bind when resolving through an interface, preventing a new factory call on everyInjector.get<IFoo>()call. - Self-referential interface factory (
addFactory<I>((i) => i.get())): The locator now detects recursive resolution for the same type and skips the executing bind, falling through to the concrete implementation. Previously this threw"Type IFoo is already being searched". ConcurrentModificationErrorduring interface lookup:_searchCompatibleBindnow iterates a snapshot ofbindsMap.entriesinstead of the live view, making in-loop writes safe under nested resolution.- Singleton instantiated multiple times via imports: Duplicate
Bindobjects created by re-imported modules now receive the cached instance from the already-registered bind, preventing repeated factory calls. Injector.get<IService>()after typed registration: A singleton registered with an explicit generic (e.g.i.addSingleton<IAuthApi>(...)) is now reachable through both the interface and the concreteruntimeType.- Keyed + unkeyed singleton on the same type:
bindsMap[type]now holds only the unkeyed bind; keyed binds live exclusively inbindsMapByKey, makingInjector.get<IClient>()order-independent.
5.0.6 #
Fixed #
- Duplicate singleton construction via imports:
_collectImportedBindscreated newBindobjects withcachedInstance == nullon every registration pass.commitBatchnow propagatescachedInstanceto duplicate binds before downstream methods run, preventing 2× extra factory calls. - Orphaned singleton instances: When two imported modules declare the same type,
commitBatchnow checks_isSingletonAlreadyRegisteredbefore callingfactoryFunction, completely preventing duplicate factory calls and leaked instances (open streams, duplicate subscriptions).
5.0.5 #
Fixed #
- Dependency injection: Singleton and lazySingleton constructors were called multiple times during module registration. The system now correctly reuses the cached instance after the first creation.
5.0.4 #
Fixed #
onExitinChildRoute: Fixed propagation of theonExitcallback across all route creation paths.
5.0.3 #
Added #
- Detailed error messages: Missing dependency errors now include which component made the request and a full dependency chain (e.g.
A ➔ B ➔ C). - Circular dependency detection: Detects infinite recursion during bind resolution and surfaces a clear, actionable error message.
- Safer resource cleanup:
CleanBindnow handlesdispose,close, andcancelmore robustly, with safe fallback forNoSuchMethodError.
5.0.2 #
Improved #
- Dependency injection: Switched from nested search to a commit-based approach for better performance.
5.0.1 #
Added #
-
Bind.lazySingleton: Creates singleton instances only on first access — useful for expensive resources that may not always be needed.i.lazySingleton<ExpensiveService>((i) => ExpensiveService()); -
Page transitions: Built-in transition system for smooth route animations.
- Presets: fade, slide, scale, rotate, and more.
- Child routes automatically inherit transitions from parent modules.
- Platform-specific styles: Cupertino (iOS/macOS) and Material (Android).
- Chainable effects:
GoTransitions.slide.toRight.withFade.
ModuleRoute('/home', module: HomeModule(), transition: GoTransitions.fadeUpwards, duration: Duration(milliseconds: 300)) ChildRoute('/details', child: (_, __) => DetailsPage(), transition: GoTransitions.slide.toRight.withFade)
5.0.0 #
Breaking Changes #
-
New
bindsAPI: Changed fromFutureOr<List<Bind<Object>>> binds()toFutureBinds binds(Injector i). Binds are now registered via injector methods instead of returning a list.// Before (4.x) FutureOr<List<Bind<Object>>> binds() => [ Bind.factory<ApiService>((i) => ApiService()), Bind.singleton<DatabaseService>((i) => DatabaseService()), ]; // After (5.x) FutureBinds binds(Injector i) { i.add<ApiService>((i) => ApiService()); i.addSingleton<DatabaseService>((i) => DatabaseService()); }
Added #
- Native injector: Removed dependency on
auto_injector. Direct registration methods:i.add(),i.addSingleton(),i.addLazySingleton(). - Performance: ~4× faster dependency resolution and reduced memory overhead.
- Better error messages: Clearer type mismatch and cycle detection errors.
4.2.2 #
4.2.0+4 #
Fixed #
- Added validation to prevent overwriting already-registered singletons for the same type and key.
4.2.0 #
4.1.0 #
4.0.0 #
Breaking Changes #
-
ModularApp.router: ReplacesMaterialApp.router.routerConfigis set automatically — remove it from your code. -
Async binds and imports:
binds()andimports()now returnFutureOr<List<T>>instead ofList<T>.// Before (3.x) List<Bind<Object>> get binds => [Bind.singleton<MyService>((i) => MyService())]; List<Module> get imports => [SharedModule()]; // After (4.x) FutureOr<List<Bind<Object>>> binds() => [Bind.singleton<MyService>((i) => MyService())]; FutureOr<List<Module>> imports() => [SharedModule()];
Added #
ModularApp.router: ExtendsMaterialApp.routerwith automatic loader display during module registration.ModularLoader: Built-in loading overlay withModularLoader.show()/ModularLoader.hide()and aCustomModularLoaderabstract class for full appearance customisation.
3.0.0 #
Breaking Changes #
-
Root route required: Modules must now declare a root
ChildRoute('/')as their entry point. An assertion error is thrown if it is missing.List<ModularRoute> get routes => [ ChildRoute('/', child: (_, __) => HomePage()), // required ChildRoute('/details', child: (_, __) => DetailsPage()), ];
2.0.3+1 #
2.0.2+1 #
Added #
InternalLogsclass for consistent debug output across route registration and bind management.
Fixed #
_registerwas not being called during route redirects, causing missing dependency injection before page construction.
Improved #
- Bind registration is skipped when no redirect occurs, reducing redundant operations and log noise.