Module Lifecycle
The documentation is constantly evolving and updated alongside the project's progress. Since it is developed in parallel with the code, some sections may temporarily refer to earlier versions of the system-these are gradually adapted to the current state of the application. If you notice any outdated information, please report it or open an Issue / Pull Request.
Documentation
# Module Lifecycle
DBM Framework modules are application components discovered from the application modules directory. A module can register services, register web routes, optionally register API routes, add template behavior, and run boot logic.
# Module manifest
Each module directory has a module.json manifest. The loader reads this file and merges the module's installed-state manifest when present. A minimal manifest includes the module key and PHP class:
{
"name": "Catalog",
"version": "1.0.0",
"key": "catalog",
"type": "plugin",
"class": "Mod\\Catalog\\CatalogModule"
}
The platform's Composer autoloader must be able to load the declared class. The manifest may also include enabled/installed state and package metadata used by the platform installer.
# Implement a module
Extend PluginModule or AbstractModule. Register services through the provided DependencyContainer and add routes through RouteBuilder.
final class CatalogModule extends PluginModule implements ApiModuleInterface
{
public function register(DependencyContainer $container): void
{
$container->singleton(
CatalogService::class,
fn($c) => new CatalogService($c->get(CatalogRepository::class))
);
}
public function registerRoutes(RouteBuilder $routes): void
{
$routes->get('/catalog', [CatalogController::class, 'index'], 'catalog.index');
}
public function registerApiRoutes(RouteBuilder $routes): void
{
$routes->get('/catalog/items', [CatalogApiController::class, 'index'], 'api.catalog.items');
}
public function boot(): void
{
// Runtime setup after the module has been discovered and registered.
}
}
Implement ApiModuleInterface when the application should discover and call registerApiRoutes(). Implement TemplateAwareInterface and bootTemplates(TemplateEngine $engine) when the module needs to register template paths or features. The framework does not call API registration just because a class has a method with that name; the interface and application integration matter.
# Discovery and boot sequence
- ModuleBootstrapper scans module.json files in the application's modules directory.
- Module manifests are loaded and cached.
- Disabled modules, missing classes, and the completed installer are skipped.
- Enabled module objects are created and registered in ModuleRegistry.
- Each module registers services; template-aware modules register template resources; each module's boot() method runs.
- The application can register module routes. API routes are exposed by modules implementing ApiModuleInterface.
ModuleManager also decides whether to boot the installer based on the installation lock, pending packages, and installer session state.
# Installing packages
ModuleInstaller delegates package extraction and validation to ModulePackageService. It copies package content into supported application directories, applies file and database migrations, writes module installation state and environment values, reports conflicts, and cleans up extracted package content. Installation is application-changing work; use the platform's installer workflow and review conflicts rather than calling the low-level installer casually.
# Practical guidance
- Keep module services namespaced under the module.
- Make service bindings explicit for interfaces and configuration.
- Use route names that are unique across the application.
- Keep module manifest key and declared module class aligned.
- Treat package migrations and copied files as part of the module's release and upgrade plan.
See the Framework Source Map for the other source areas.