Source code for injectable.injection.injectable_factory_decorator

from typing import TypeVar, Callable

from injectable.container.injection_container import InjectionContainer
from injectable.errors.injectable_load_error import InjectableLoadError
from injectable.common_utils import get_caller_filepath

T = TypeVar("T")


[docs]def injectable_factory( dependency: T = None, *, qualifier: str = None, primary: bool = False, namespace: str = None, group: str = None, singleton: bool = False, ) -> Callable[..., Callable[..., T]]: """ Function decorator to mark it as a injectable factory for the dependency. At least one of ``dependency`` or ``qualifier`` parameters need to be defined. An :class:`InjectableLoadError <injectable.errors.InjectableLoadError>` will be raised if none are defined. .. note:: This decorator shall be the first decorator of the function since only the received function will be registered as an injectable factory .. note:: All files using this decorator will be executed when :meth:`load_injection_container <injectable.load_injection_container>` is invoked. :param dependency: (optional) the dependency class for which the factory will be registered to. Defaults to None. :param qualifier: (optional) string qualifier for which the factory will be registered to. Defaults to None. :param primary: (optional) marks the factory as primary for the dependency resolution in ambiguous cases. Defaults to False. :param namespace: (optional) namespace in which the factory will be registered. Defaults to :const:`injectable.constants.DEFAULT_NAMESPACE`. :param group: (optional) group to be assigned to the factory. Defaults to None. :param singleton: (optional) when True the factory will be used to instantiate a singleton, i.e. only one call to the factory will be made and the created instance will be shared globally. Defaults to False. Usage:: >>> from injectable import injectable_factory >>> from foo import Foo >>> >>> @injectable_factory(Foo) ... def foo_factory() -> Foo: ... return Foo(...) """ if not dependency and not qualifier: raise InjectableLoadError("No dependency class nor a qualifier were specified") def decorator(fn: Callable[..., T]) -> Callable[..., T]: caller_filepath = get_caller_filepath() if caller_filepath == InjectionContainer.LOADING_FILEPATH: InjectionContainer._register_factory( fn, caller_filepath, dependency, qualifier, primary, namespace, group, singleton, ) return fn return decorator