Injectable trait — the #[injectable] proc-macro generates that implementation for you. The framework constructs and caches providers in the ProviderRegistry, then makes them available to controllers and other providers through Axum’s State extractor.
Marking a type as injectable
Apply#[injectable] to a struct to generate the Injectable trait implementation. nestrs calls construct to build the type, injecting any dependencies it finds in the registry:
Arc<T> where T is a registered provider is resolved from the registry automatically.
construct is synchronous. Do not call block_on or perform I/O inside it — use on_module_init for async setup.Provider scopes
Control how long a provider instance lives with thescope argument:
Registering providers in a module
List your providers in theproviders field of the enclosing module. Providers that other modules need must also appear in exports:
Injecting providers into controllers
Controllers access their providers via Axum’sState extractor. The #[routes(state = T)] macro wires the service type into the router, and handler functions can take service: Arc<T> directly:
Multiple providers per controller (tuple state)
If a controller needs multiple services, specify a tuple instate:
ProviderRegistry via RouteStateFromRegistry. Handlers only receive the services they declare. Explicit State(service): State<Arc<T>> remains supported as well.
Injecting providers into other providers
When one provider depends on another, declare the dependency as anArc<T> field and ensure both types are registered in the same module (or that the dependency is exported from an imported module):
Lifecycle hooks
Injectable provides five async hooks (all default to no-ops): on_module_init, on_application_bootstrap, on_before_application_shutdown, on_application_shutdown, and on_module_destroy.
listen() first eagerly constructs all singleton providers (in registration order), then runs on_module_init across all singletons, then on_application_bootstrap, and only then binds the listener — hooks run before the server accepts traffic. Within each hook phase, providers run in dependency order (construction dependencies first, ties broken by registration order). On graceful shutdown the phases run in reverse: on_before_application_shutdown → on_application_shutdown → on_module_destroy, each in reverse initialization order so dependencies are torn down after their dependents.
Custom factory providers
Useregister_use_factory when construction order must be explicit or when you need to close a provider dependency cycle without calling registry.get() eagerly inside another type’s construct: