Providers are the services, repositories, and utilities that your application logic depends on. In nestrs, any type can become a provider by implementing the 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:
nestrs infers dependencies from the struct fields. Any field of type 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 the scope argument:
Registering providers in a module
List your providers in the providers field of the enclosing module. Providers that other modules need must also appear in exports:
To share a provider across modules:
Injecting providers into controllers
Controllers access their providers via Axum’s State extractor. The #[routes(state = T)] macro wires the service type into the router:
Injecting providers into other providers
When one provider depends on another, declare the dependency as an Arc<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 four async hooks (all default to no-ops):
Lifecycle hooks only run for singleton providers. Transient providers are constructed on demand and do not receive hook calls.
Custom factory providers
Use register_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:
All custom provider variants
Keep factory closures non-async. Defer I/O to on_module_init on the produced type, or to ConfigurableModuleBuilder::for_root_async for module-level configuration.