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 DependencyResolver singleton used by pages, form actions, and component renderers throughout the framework. Import it as from next.deps import resolver when you need to call resolver.resolve_dependencies from 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>#
priority: ClassVar[int] = 100#
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.

dependency: object | None#
__init__(dependency: object | None = None) None#
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.

__init__(cycle: list[str]) None[source]#

Record the offending dependency chain for the error message.

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.

get(key: str) object[source]#

Return the cached value, _IN_PROGRESS, or _CACHE_MISS.

set(key: str, value: object) None[source]#

Store a finished resolution under the given key.

mark_in_progress(key: str) None[source]#

Mark the key as currently being resolved for cycle detection.

unmark_in_progress(key: str) None[source]#

Clear the in-progress marker for the key.

__len__() int[source]#

Return the number of stored values.

__contains__(key: str) bool[source]#

Return membership in the backing 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.

request: HttpRequest | None#
form: object | None#
url_kwargs: Mapping[str, Any]#
context_data: Mapping[str, Any]#
cache: DependencyCache#
stack: list[str]#
cleaned_data: Mapping[str, Any] | None#
__init__(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) None#

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.