Documentation Index
Fetch the complete documentation index at: https://mintlify.com/khode-io/nest-dart/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Modular class provides a clean, static API for accessing dependency injection services and router configuration throughout your Flutter application. It offers a similar API to Flutter Modular but is built on Nest’s powerful DI container.
All Modular static methods require ModularApp to be initialized first. Calling these methods before initialization will throw a FlutterError.
Service Resolution Methods
get<T>()
Retrieve a service instance from the global container.
static T get<T extends Object>({String? instanceName})
The type of service to retrieve. Must be registered in a module.
Optional named instance identifier. Use when you have multiple instances of the same type registered with different names.
The resolved service instance.
Usage Example
// Get a service
final userService = Modular.get<UserService>();
final user = await userService.getCurrentUser();
// Get a named instance
final primaryDb = Modular.get<Database>(instanceName: 'primary');
final cacheDb = Modular.get<Database>(instanceName: 'cache');
class UserProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authService = Modular.get<AuthService>();
final userRepo = Modular.get<UserRepository>();
return FutureBuilder(
future: userRepo.getUserProfile(authService.currentUserId),
builder: (context, snapshot) {
// Build UI
},
);
}
}
getWithParams<T>()
Retrieve a service instance that requires parameters for construction.
static T getWithParams<T extends Object>(dynamic param1, [dynamic param2])
The type of service to retrieve.
First parameter to pass to the factory function.
Optional second parameter to pass to the factory function.
The resolved service instance created with the provided parameters.
Usage Example
// In your module
class AppModule extends Module {
@override
List<Provider> get providers => [
Provider.factory<UserRepository>(
(userId, tenantId) => UserRepository(userId, tenantId),
),
];
}
// Using getWithParams
final userRepo = Modular.getWithParams<UserRepository>(
'user123',
'tenant456',
);
getAsync<T>()
Retrieve an asynchronously initialized service instance.
static Future<T> getAsync<T extends Object>({String? instanceName})
The type of service to retrieve.
Optional named instance identifier.
A future that completes with the resolved service instance.
Usage Example
// In your module - register async service
class AppModule extends Module {
@override
List<Provider> get providers => [
Provider.asyncSingleton<Database>(
() async => await Database.initialize(),
),
];
}
// Using getAsync
final database = await Modular.getAsync<Database>();
final users = await database.query('users');
isRegistered<T>()
Check if a service type is registered in the container.
static bool isRegistered<T extends Object>({String? instanceName})
The type of service to check.
Optional named instance identifier.
true if the service is registered, false otherwise.
Usage Example
if (Modular.isRegistered<AuthService>()) {
final auth = Modular.get<AuthService>();
// Use auth service
} else {
// Handle missing service
print('AuthService not registered');
}
// Check named instances
if (Modular.isRegistered<Database>(instanceName: 'cache')) {
final cacheDb = Modular.get<Database>(instanceName: 'cache');
}
getAvailableServices()
Get a set of all registered service types.
static Set<Type> getAvailableServices()
A set containing all registered service types.
Usage Example
final services = Modular.getAvailableServices();
for (final serviceType in services) {
print('Available: $serviceType');
}
// Check if specific service exists
if (services.contains(UserService)) {
final userService = Modular.get<UserService>();
}
Context-Based Methods
of()
Get the ApplicationContainerNotifier from a BuildContext. This provides reactive access to the container.
static ApplicationContainerNotifier of(BuildContext context)
The build context to search for the container provider.
returns
ApplicationContainerNotifier
The container notifier from the widget tree.
Throws FlutterError if no ApplicationContainerProvider is found in the widget tree.
Usage Example
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final containerNotifier = Modular.of(context);
// Access services
final userService = containerNotifier.get<UserService>();
return ListenableBuilder(
listenable: containerNotifier,
builder: (context, child) {
// Rebuild when container changes
return Text('Services: ${containerNotifier.getAvailableServices().length}');
},
);
}
}
containerOf()
Get the raw ApplicationContainer from a BuildContext.
static ApplicationContainer containerOf(BuildContext context)
The build context to search for the container.
The raw container instance.
Usage Example
class DebugPanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
final container = Modular.containerOf(context);
final modules = container.modules;
return Column(
children: [
Text('Registered Modules: ${modules.length}'),
for (final module in modules)
Text('- ${module.runtimeType}'),
],
);
}
}
Router Configuration
router()
Create and configure a GoRouter instance from the root module’s routes.
static GoRouter router(
GoRouter Function(GoRouter router) configurator, {
Module? rootModule,
bool forceRecreate = false,
})
A callback function that receives the base router and returns a configured router. Use this to customize router settings.Modular.router((router) {
return GoRouter(
routes: router.routes,
initialLocation: '/home',
debugLogDiagnostics: true,
redirect: (context, state) {
// Custom redirect logic
},
);
})
Optional root module. If not provided, uses the module from ModularApp.
Force recreation of the router even if a cached version exists. Useful when routes change dynamically.
The configured GoRouter instance.
The router is cached by default to prevent recreation during hot reloads. Use forceRecreate: true or clearRouterCache() to regenerate routes.
Usage Example
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'My App',
routerConfig: Modular.router(
(router) => GoRouter(
routes: router.routes,
initialLocation: '/splash',
debugLogDiagnostics: kDebugMode,
redirect: (context, state) {
final authService = Modular.get<AuthService>();
final isLoggedIn = authService.isAuthenticated;
if (!isLoggedIn && state.location != '/login') {
return '/login';
}
return null;
},
errorBuilder: (context, state) => ErrorScreen(state.error),
),
),
);
}
}
clearRouterCache()
Clear the cached router instance, forcing recreation on next router() call.
static void clearRouterCache()
Usage Example
// After dynamically updating routes
Modular.clearRouterCache();
// Next router() call will recreate the router with new routes
final newRouter = Modular.router((router) => router);
cachedRouter
Get the currently cached router instance (for debugging).
static GoRouter? get cachedRouter
The cached router instance, or null if no router is cached.
isRouterCached
Check if a router is currently cached.
static bool get isRouterCached
true if a router is cached, false otherwise.
rootModule
Get the current root module.
static Module? get rootModule
The root module instance, or null if not initialized.
Error Handling
Initialization Errors
try {
final service = Modular.get<MyService>();
} catch (e) {
if (e is FlutterError) {
// Handle: ModularApp not initialized
print('Make sure ModularApp is initialized');
}
}
Service Not Found
try {
final service = Modular.get<UnregisteredService>();
} catch (e) {
// Handle: Service not registered in any module
print('Service not found: $e');
}
Best Practices
Use Modular.of(context) for reactive updates: When you need to rebuild widgets based on container changes, use of() instead of static get().
Cache router in production: The default router caching prevents unnecessary recreations during hot reloads, improving development experience.
Don’t call get<T>() in widget constructors: Widget constructors can be called before ModularApp is initialized. Instead, call it in build() or initState().
See Also