Dependency injection reference#
Module summary#
next.deps exposes the resolver, the parameter providers, the dependency cache, and the public markers used in annotations.
Public API#
Resolver#
Walk a callable’s signature and fill its parameters from the context.
DependencyResolver is the orchestrator consumed by page views, form actions, and component renderers. It instantiates every subclass registered under RegisteredParameterProvider._registry on first use. Providers register by simply importing their module, which runs the __init_subclass__ hook on RegisteredParameterProvider.
- next.deps.resolver.cached_signature(func: Callable[..., Any]) inspect.Signature[source]#
Return inspect.signature(func), memoised per callable.
- next.deps.resolver.cached_type_hints(func: Callable[..., Any]) dict[str, Any][source]#
Return get_type_hints(func), memoised per callable.
- class next.deps.resolver.DependencyResolver(*providers: ParameterProvider | RegisteredParameterProvider)[source]#
Build keyword-arguments for a callable by consulting registered providers.
- EXPLICIT_RESOLVE_KEYS: ClassVar[frozenset[str]] = frozenset({'_cache', '_context_data', '_stack', 'cleaned_data', 'form', 'request'})#
- __init__(*providers: ParameterProvider | RegisteredParameterProvider) None[source]#
Initialise with explicit providers or defer to the auto-registry.
- register_dependency(name: str, callable_dep: Callable[..., Any]) Callable[..., Any][source]#
Register a callable as a dependency reachable through Depends(“name”).
- get_dependency(name: str) Callable[..., Any] | None[source]#
Return the callable bound to name, or None when nothing is bound.
- unregister_dependency(name: str) None[source]#
Drop the binding for name, tolerating a name that has none.
- dependency(name: str) Callable[[Callable[..., Any]], Callable[..., Any]][source]#
Return a decorator that registers the callable under the given name.
- add_provider(provider: ParameterProvider) None[source]#
Append a provider after the existing list.
- prepend_provider(provider: ParameterProvider) None[source]#
Put provider ahead of every other one, so it matches first.
The auto-registered providers load first, otherwise they would be placed in front of the newcomer on their own first use.
- remove_provider(provider: ParameterProvider) None[source]#
Drop provider from the list, tolerating one that is not in it.
- register(provider: ParameterProvider | type[ParameterProvider]) ParameterProvider | type[ParameterProvider][source]#
Register a provider, accepting either a class or an instance.
- current_callable() Callable[..., Any] | None[source]#
Return the callable being resolved, or None outside a resolve.
A provider reads it when the parameter alone cannot answer, because inspect.Parameter carries the annotation as it was written while get_type_hints on the owning callable resolves a string one. Resolving a dependency nests, so the innermost callable is returned.
- resolve(func: Callable[..., T], context: ResolutionContext) dict[str, Any][source]#
Return keyword arguments ready to call func with the given context.
- resolve_dependencies(func: Callable[..., Any], **context) dict[str, Any][source]#
Resolve func from a loose kwargs mapping and build a context object.
- resolve_with_template_context(func: Callable[..., Any], *, request: HttpRequest | None = None, template_context: dict[str, Any] | None = None, _cache: dict[str, Any] | DependencyCache | None = None, _stack: list[str] | None = None) dict[str, Any][source]#
Resolve func for component callables using template context.
Keys from EXPLICIT_RESOLVE_KEYS are stripped from the context data so that name-based providers cannot shadow dedicated providers such as HttpRequestProvider on a parameter literally named request.
- next.deps.resolver.resolver#
The shared
DependencyResolversingleton used by pages, form actions, and component renderers throughout the framework. Import it asfrom next.deps import resolverwhen you need to callresolver.resolve_dependenciesfrom a custom provider or a test helper.
Providers#
ParameterProvider is the minimal protocol the resolver consumes.
RegisteredParameterProvider is the auto-registered base used by the built-in providers.
Subclasses join the resolver’s registry through __init_subclass__, so the resolver instantiates them on first use without an explicit import.
A subclass reaches the active resolver through the resolver class attribute, which is bound to the shared singleton.
resolver.current_callable() answers which callable the resolve is for, or None outside a resolve.
A provider reads it when the parameter alone cannot decide, since inspect.Parameter carries the annotation as it was written while get_type_hints on the owning callable resolves a string one.
HttpRequestProvider uses exactly that to claim a request: "HttpRequest" parameter written under a deferred annotation.
Parameter-provider contracts and the auto-registry ABC.
ParameterProvider is the minimal Protocol consumed by DependencyResolver. RegisteredParameterProvider is the ABC used by built-in providers that ship with the framework. Subclasses of the ABC join the module-level _registry through __init_subclass__, which lets the resolver instantiate them on first use without importing them explicitly. The resolver consults providers in ascending priority order, so a lower priority value is checked first.
- class next.deps.providers.ParameterProvider(*args, **kwargs)[source]#
Minimal protocol consumed by DependencyResolver.
- can_handle(param: inspect.Parameter, context: ResolutionContext) bool[source]#
Return True when this provider owns the parameter.
- resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
Return the resolved value for the parameter.
- __init__(*args, **kwargs)#
- class next.deps.providers.RegisteredParameterProvider[source]#
Auto-registered base used by built-in providers shipped with the framework.
- resolver: ClassVar[DependencyResolver] = <next.deps.resolver.DependencyResolver object>#
- classmethod __init_subclass__(**kwargs) None[source]#
Track concrete subclasses for lazy instantiation by the resolver.
- abstractmethod can_handle(param: inspect.Parameter, context: ResolutionContext) bool[source]#
Return True when this provider owns the parameter.
- abstractmethod resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
Return the resolved value for the parameter.
Markers#
Annotation markers and the default Depends provider.
DDependencyBase is the shared parent for type-annotation markers such as DForm or DUrl. Depends is a dataclass default value used to request dependency resolution by name, by callable, or by constant injection. DependsProvider is the built-in parameter provider that handles the Depends marker and registers itself through RegisteredParameterProvider.
- class next.deps.markers.DDependencyBase[source]#
Shared base for annotation markers such as DForm and DUrl.
- class next.deps.markers.Depends(dependency: object | None = None)[source]#
Mark a parameter as a dependency resolved by the resolver.
Use as a default parameter value. Depends(“name”) resolves a registered callable by name. Depends(callable) calls a factory with DI-resolved arguments. Depends(value) injects a constant value directly. Depends() resolves by the parameter name.
- class next.deps.markers.DependsProvider(resolver: DependencyResolver)[source]#
Provider that resolves parameters whose default is a Depends marker.
- priority = 10#
- __init__(resolver: DependencyResolver) None[source]#
Store the resolver used for nested dependency calls.
- can_handle(param: inspect.Parameter, _context: ResolutionContext) bool[source]#
Return True when the parameter default is a Depends marker.
- resolve(param: inspect.Parameter, context: ResolutionContext) object[source]#
Resolve a Depends marker by name, callable, or constant.
Cache#
Sentinels, cycle error, and per-resolution cache used during DI resolution.
The DependencyCache object accumulates resolved dependency values during a single resolution pass. The _IN_PROGRESS and _CACHE_MISS sentinels separate the three cache-lookup outcomes (hit, miss, and in-progress) without collapsing None-valued hits into misses.
- next.deps.cache.get_request_dep_cache(request: object | None) dict[str, Any] | None[source]#
Return the dispatch-scoped dep cache attached to request, or None.
FormActionDispatch.dispatch attaches its dep_cache dict to the request so downstream renderers (page context, component context) can rejoin the same DI cache during a validation-failure re-render. Consumers wrap the returned dict in DependencyCache to share state.
- exception next.deps.cache.DependencyCycleError(cycle: list[str])[source]#
Raised when dependency resolution re-enters a key already in progress.
- class next.deps.cache.DependencyCache(backing_dict: dict[str, Any] | None = None)[source]#
Store resolved dependency values and detect cycles via in-progress keys.
- __init__(backing_dict: dict[str, Any] | None = None) None[source]#
Initialise storage, optionally sharing an externally owned dict.
Context#
Resolution-context snapshot passed to providers during DI resolution.
ResolutionContext collects request, form, URL kwargs, and template context data into a single immutable view. Providers read from this object without mutating it. RESERVED_KEYS lists the kwarg names that DependencyResolver.resolve_dependencies treats as fixed inputs rather than URL kwargs.
- class next.deps.context.ResolutionContext(request: HttpRequest | None, form: object | None, url_kwargs: Mapping[str, Any], context_data: Mapping[str, Any], cache: DependencyCache, stack: list[str] = <factory>, cleaned_data: Mapping[str, Any] | None = None)[source]#
Immutable snapshot of the inputs available during dependency resolution.
- cache: DependencyCache#
RESERVED_KEYS lists the names (request, form, cleaned_data, _cache, _stack, _context_data) stripped from name-based resolution.
A context key cannot shadow a reserved resolver input.
DependencyResolver.EXPLICIT_RESOLVE_KEYS is the class-level alias of the same frozenset.
The resolver reads self.EXPLICIT_RESOLVE_KEYS, which a subclass may override.
See Dependency resolver for the resolution detail.
Signals#
See Signals reference for the provider_registered signal.
Checks#
The dependency injection layer registers no Django system checks.
See also#
See also
Dependency injection for the topic guide. Dependency resolver for the resolver internals.