Source code for injectable.injection.injectable_decorator
from typing import TypeVar
from injectable.container.injection_container import InjectionContainer
from injectable.common_utils import get_caller_filepath
T = TypeVar("T")
[docs]def injectable(
cls: T = None,
*,
qualifier: str = None,
primary: bool = False,
namespace: str = None,
group: str = None,
singleton: bool = False,
) -> T:
"""
Class decorator to mark it as an injectable dependency.
This decorator accepts customization parameters but can be invoked without the
parenthesis when no parameter will be specified.
.. note::
All files using this decorator will be executed when
:meth:`load_injection_container <injectable.load_injection_container>` is
invoked.
:param cls: (cannot be explicitly passed) the decorated class. This will be
automatically passed to the decorator by Python magic.
:param qualifier: (optional) string qualifier for the injectable to be registered
with. Defaults to None.
:param primary: (optional) marks the injectable as primary for resolution in
ambiguous cases. Defaults to False.
:param namespace: (optional) namespace in which the injectable will be registered.
Defaults to :const:`injectable.constants.DEFAULT_NAMESPACE`.
:param group: (optional) group to be assigned to the injectable. Defaults to None.
:param singleton: (optional) when True the injectable will be a singleton, i.e. only
one instance of it will be created and shared globally. Defaults to False.
Usage::
>>> from injectable import injectable
>>>
>>> @injectable
... class Foo:
... ...
"""
def decorator(klass: T, direct_call: bool = False) -> T:
steps_back = 3 if direct_call else 2
caller_filepath = get_caller_filepath(steps_back)
if caller_filepath == InjectionContainer.LOADING_FILEPATH:
InjectionContainer._register_injectable(
klass, caller_filepath, qualifier, primary, namespace, group, singleton
)
return klass
return decorator(cls, True) if cls is not None else decorator