injectable¶
This is the injectable’s public API.
See also
The Usage Examples section presents a collection of examples on how to use this API.
-
injectable.
load_injection_container
(search_path: str = None, *, default_namespace: str = 'DEFAULT_NAMESPACE', encoding: str = 'utf-8')[source]¶ Loads injectables under the search path to a shared injection container under the designated namespaces.
Parameters: - search_path – (optional) path under which to search for injectables. Can be either a relative or absolute path. Defaults to the caller’s file directory.
- default_namespace – (optional) designated namespace for registering
injectables which does not explicitly request to be addressed in a
specific namespace. Defaults to
injectable.constants.DEFAULT_NAMESPACE
. - encoding – (optional) defines which encoding to use when reading project files
to discover and register injectables. Defaults to
utf-8
.
Usage:
>>> from injectable import load_injection_container >>> load_injection_container()
Note
This method will not scan any file already scanned by previous calls to it. Multiple invocations to different search paths will add found injectables into the injection container without clearing previously loaded ones but never loading a same injectable more than once.
New in version 3.4.0.
-
class
injectable.
InjectionContainer
[source]¶ InjectionContainer globally manages injection namespaces and the respective injectables registries.
This class shouldn’t be used directly and will be removed from the injectable’s public API in the future.
Invoking
load_injection_container()
is the only necessary action before injecting dependencies. Attempting to call an autowired function before invokingload_injection_container()
will log a warning indicating that the injection container is empty.This class is not meant to be instantiated and will raise an error if instantiation is attempted.
Deprecated since version 3.4.0: This class will be removed from the public API in the future.
-
classmethod
load
(search_path: str = None, *, default_namespace: str = 'DEFAULT_NAMESPACE')[source]¶ Loads injectables under the search path to the
InjectionContainer
under the designated namespaces.Parameters: - search_path – (optional) path under which to search for injectables. Can be either a relative or absolute path. Defaults to the caller’s file directory.
- default_namespace – (optional) designated namespace for registering
injectables which does not explicitly request to be addressed in a
specific namespace. Defaults to
injectable.constants.DEFAULT_NAMESPACE
.
Usage:
>>> from injectable import InjectionContainer >>> InjectionContainer.load()
Note
This method will not scan any file more than once regardless of being called successively. Multiple invocations to different search paths will add found injectables to the
InjectionContainer
without clearing previously found ones.Deprecated since version 3.4.0: This method will be removed from the public API in the future. Use
load_injection_container()
instead.
-
classmethod
-
class
injectable.
Injectable
(constructor: callable, unique_id: str = <factory>, primary: bool = False, group: Optional[str] = None, singleton: bool = False)[source]¶ Injectable is the low-level container class in which information regarding an injectable dependency is stored for registering in a namespace.
This class is not meant for direct usage. It should be used in conjunction with the
injectable.testing
module utilities for testing purposes only.Parameters: - constructor – callable to be used as constructor when injecting.
- unique_id – (optional) unique identifier for the injectable which prevents duplicates of the same injectable to be registered. Defaults to a UUID generated at initialization time.
- primary – (optional) marks the injectable as primary for resolution in ambiguous cases. Defaults to False.
- group – (optional) group to be assigned to the injectable. Defaults to None.
- 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.
-
injectable.
autowired
(func: T) → T[source]¶ Function decorator to setup dependency injection autowiring.
Only parameters annotated with
Autowired
will be autowired for injection.If no parameter is annotated with
Autowired
anAutowiringError
will be raised.An
AutowiringError
will also be raised if a parameter annotated withAutowired
is given a default value or if a non Autowired-annotated positional parameter is placed after an Autowired-annotated positional parameter.Before attempting to call an autowired function make sure
load_injection_container
was invoked.Note
This decorator can be applied to any function, not only an __init__ method.
Note
This decorator accepts no arguments and must be used without trailing parenthesis.
Usage:
>>> from injectable import Autowired, autowired >>> >>> @autowired ... def foo(dep: Autowired(...)): ... ...
-
class
injectable.
Autowired
[source]¶ Autowired type annotation marks a parameter to be autowired for injection.
Autowired parameters must be last in declaration if there are others which aren’t autowired. Also, autowired parameters must not be given default values.
This type annotation does not performs the function autowiring by itself. The function must be decorated with
@autowired
for autowiring.Parameters: - dependency – class, base class or qualifier of the dependency to be used
for lookup among the registered injectables. Can be wrapped in a typing
sequence, e.g.
List[...]
, to inject a list containing all matching injectables. Can be wrapped in a optional, e.g.Optional[...]
, to inject None if no matches are found to inject.Optional[List[...]]
is valid and will inject an empty list if no matches are found to inject. - namespace – (optional) namespace in which to look for the dependency.
Defaults to
injectable.constants.DEFAULT_NAMESPACE
. - group – (optional) group to filter out other injectables outside of this group. Defaults to None.
- exclude_groups – (optional) list of groups to be excluded. Defaults to None.
- lazy – (optional) when True will return an instance which will automatically initialize itself when first used but not before that. Defaults to False.
Usage:
>>> from injectable import Autowired, autowired >>> >>> @autowired ... def foo(arg: Autowired("qualifier")): ... ...
- dependency – class, base class or qualifier of the dependency to be used
for lookup among the registered injectables. Can be wrapped in a typing
sequence, e.g.
-
injectable.
injectable_factory
(dependency: T = None, *, qualifier: str = None, primary: bool = False, namespace: str = None, group: str = None, singleton: bool = False) → Callable[[...], Callable[[...], T]][source]¶ Function decorator to mark it as a injectable factory for the dependency.
At least one of
dependency
orqualifier
parameters need to be defined. AnInjectableLoadError
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
load_injection_container
is invoked.Parameters: - dependency – (optional) the dependency class for which the factory will be registered to. Defaults to None.
- qualifier – (optional) string qualifier for which the factory will be registered to. Defaults to None.
- primary – (optional) marks the factory as primary for the dependency resolution in ambiguous cases. Defaults to False.
- namespace – (optional) namespace in which the factory will be registered.
Defaults to
injectable.constants.DEFAULT_NAMESPACE
. - group – (optional) group to be assigned to the factory. Defaults to None.
- 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(...)
-
injectable.
injectable
(cls: T = None, *, qualifier: str = None, primary: bool = False, namespace: str = None, group: str = None, singleton: bool = False) → T[source]¶ 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
load_injection_container
is invoked.Parameters: - cls – (cannot be explicitly passed) the decorated class. This will be automatically passed to the decorator by Python magic.
- qualifier – (optional) string qualifier for the injectable to be registered with. Defaults to None.
- primary – (optional) marks the injectable as primary for resolution in ambiguous cases. Defaults to False.
- namespace – (optional) namespace in which the injectable will be registered.
Defaults to
injectable.constants.DEFAULT_NAMESPACE
. - group – (optional) group to be assigned to the injectable. Defaults to None.
- 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: ... ...
-
injectable.
inject
(dependency: Union[Type[T], str], *, namespace: str = None, group: str = None, exclude_groups: Sequence[str] = None, lazy: bool = False, optional: bool = False) → T[source]¶ Injects the requested dependency by instantiating a new instance of it or a singleton instance if specified by the injectable. Returns an instance of the requested dependency.
One can use this method directly for injecting dependencies though this is not recommended. Use the
@autowired
decorator and theAutowired
type annotation for dependency injection to be automatically wired to a function’s call instead.Will log a warning indicating that the injection container is empty when invoked before
load_injection_container
is called.Raises
InjectionError
when unable to resolve the requested dependency. This can be due to a variety of reasons: the requested dependency wasn’t loaded into the container; the namespace isn’t correct; the group isn’t correct; there are multiple injectables for the dependency and none or multiple are marked as primary. When parameteroptional
isTrue
no error will be raised when no injectable that matches requested qualifier/class and group is found in the specified namespace though in ambiguous cases that resolving a primary injectable is impossible an error will still be raised.Parameters: - dependency – class, base class or qualifier of the dependency to be used for lookup among the registered injectables.
- namespace – (optional) namespace in which to look for the dependency. Defaults
to
injectable.constants.DEFAULT_NAMESPACE
. - group – (optional) group to filter out other injectables outside of this group. Defaults to None.
- exclude_groups – (optional) list of groups to be excluded. Defaults to None.
- lazy – (optional) when True will return an instance which will automatically initialize itself when first used but not before that. Defaults to False.
- optional – (optional) when True this function returns None if no injectable
matches the qualifier/class and group inside the specified namespace instead
of raising an
InjectionError
. Ambiguous cases where resolving a primary injectable is impossible will still raiseInjectionError
. Defaults to False.
Usage:
>>> from foo import Foo >>> from injectable import inject >>> >>> class Bar: ... def __init__(self, foo: Foo = None): ... self.foo = foo or inject(Foo)
-
injectable.
inject_multiple
(dependency: Union[Type[T], str], *, namespace: str = None, group: str = None, exclude_groups: Sequence[str] = None, lazy: bool = False, optional: bool = False) → List[T][source]¶ Injects all injectables that resolves to the specified dependency. Returns a list of instances matching the requested dependency.
One can use this method directly for injecting dependencies though this is not recommended. Use the
@autowired
decorator and theAutowired
type annotation for dependency injection to be automatically wired to a function’s call instead.Logs a warning indicating that the injection container is empty when invoked before
load_injection_container
is called.Raises
InjectionError
when unable to resolve the requested dependency. This can be due to a variety of reasons: there is no injectable loaded into the container that matches the dependency; the namespace isn’t correct; the group specifications aren’t correct. When parameteroptional
isTrue
no error will be raised when no injectable that matches requested qualifier/class and group is found in the specified namespace.Parameters: - dependency – class, base class or qualifier of the dependency to be used for lookup among the registered injectables.
- namespace – (optional) namespace in which to look for the dependency. Defaults
to
injectable.constants.DEFAULT_NAMESPACE
. - group – (optional) group to filter out other injectables outside of this group. Defaults to None.
- exclude_groups – (optional) list of groups to be excluded. Defaults to None.
- lazy – (optional) when True will returned instances will automatically initialize themselves when first used but not before that. Defaults to False.
- optional – (optional) when True this function returns an empty list if no injectable matches the qualifier/class and group inside the specified namespace. Defaults to False.
Usage:
>>> from com import AbstractService >>> from injectable import inject_multiple >>> from typing import Sequence >>> >>> class Foo: ... def __init__(self, services: Sequence[AbstractService] = None): ... self.services = services or inject_multiple(AbstractService)