Overview
The Modular class provides a unified interface for managing the dependency injection container in Dart Frog applications. It combines container initialization, service registration, and context-based service access in a single, easy-to-use API.
Class: Modular
Static Methods
initialize()
Initializes the application container with the provided module configuration.
static Future<void> initialize(Module appModule)
The root application module containing all service registrations and configurations.
This method must be called before accessing any services through Modular.get() or Modular.of(context). It waits for the container to be fully ready before resolving.
Example:
// In your _middleware.dart file
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../app_module.dart';
Handler middleware(Handler handler) {
return handler
.use(nestFrogMiddleware(AppModule()));
}
get<T>()
Retrieves a service instance directly from the container.
static T get<T extends Object>()
The type of service to retrieve from the container.
The resolved service instance of type T.
Throws an Exception if the container is not initialized. Always call Modular.initialize() first, typically through nestFrogMiddleware().
Example:
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../services/user_service.dart';
Response onRequest(RequestContext context) {
// Direct container access
final userService = Modular.get<UserService>();
final users = userService.getAllUsers();
return Response.json(
body: users.map((u) => u.toJson()).toList(),
);
}
of()
Creates a ModularContext wrapper for accessing services from the request context.
static ModularContext of(RequestContext context)
The Dart Frog request context to wrap.
A context wrapper that provides service access with automatic fallback to the container.
Example:
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../services/auth_service.dart';
import '../services/user_service.dart';
Future<Response> onRequest(RequestContext context) async {
// Context-based service access
final authService = Modular.of(context).get<AuthService>();
final userService = Modular.of(context).get<UserService>();
final token = context.request.headers['Authorization'];
final user = await authService.validateToken(token);
if (user == null) {
return Response(statusCode: 401);
}
final profile = await userService.getUserProfile(user.id);
return Response.json(body: profile.toJson());
}
Static Properties
container
Provides direct access to the underlying ApplicationContainer instance.
static ApplicationContainer get container
The initialized application container instance.
Throws an Exception if the container is not initialized.
Example:
// Access container directly for advanced scenarios
final container = Modular.container;
final hasService = container.has<MyService>();
isInitialized
Checks whether the container has been initialized.
static bool get isInitialized
true if the container is initialized, false otherwise.
Example:
if (Modular.isInitialized) {
final service = Modular.get<MyService>();
}
Testing Methods
reset()
Resets the container to its uninitialized state. Primarily used for testing.
static Future<void> reset()
This method is useful in test suites to ensure a clean state between tests.
Example:
// In your test tearDown
tearDown(() async {
await Modular.reset();
});
Class: ModularContext
A context wrapper that provides service access with automatic fallback behavior.
Methods
get<T>()
Retrieves a service from the request context, falling back to the container if not found.
T get<T extends Object>()
The type of service to retrieve.
The resolved service instance.
First attempts to read from RequestContext, then falls back to Modular.get() if not available in the context.
Example:
final modularContext = Modular.of(context);
final service = modularContext.get<UserService>();
has<T>()
Checks if a service is available in the request context.
bool has<T extends Object>()
The type of service to check for.
true if the service is available in the context, false otherwise.
Example:
final modularContext = Modular.of(context);
if (modularContext.has<AuthService>()) {
final authService = modularContext.get<AuthService>();
}
Properties
context
Provides access to the underlying RequestContext.
RequestContext get context
The wrapped Dart Frog request context.
Example:
final modularContext = Modular.of(context);
final request = modularContext.context.request;
final headers = request.headers;
Complete Usage Example
// routes/_middleware.dart
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../modules/app_module.dart';
Handler middleware(Handler handler) {
return handler.use(nestFrogMiddleware(AppModule()));
}
// routes/users/index.dart
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../../services/user_service.dart';
import '../../services/logger_service.dart';
Future<Response> onRequest(RequestContext context) async {
// Get services using Modular.of(context)
final userService = Modular.of(context).get<UserService>();
final logger = Modular.of(context).get<LoggerService>();
try {
final users = await userService.findAll();
logger.info('Retrieved ${users.length} users');
return Response.json(
body: {
'users': users.map((u) => u.toJson()).toList(),
},
);
} catch (e) {
logger.error('Failed to retrieve users: $e');
return Response.json(
statusCode: 500,
body: {'error': 'Internal server error'},
);
}
}
// Alternative: Direct access with Modular.get()
import 'package:dart_frog/dart_frog.dart';
import 'package:nest_frog/nest_frog.dart';
import '../../services/config_service.dart';
Response onRequest(RequestContext context) {
// Direct container access (no context needed)
final config = Modular.get<ConfigService>();
return Response.json(
body: {
'version': config.appVersion,
'environment': config.environment,
},
);
}