Dependency injection container for Python3
Project description
pyInjection
pyInjector is a .Net style dependency injection container built for Python3 and utilising the typing module.
- Register
type
,instance
andlambda
functions against a base type for constructor injecting. - Supports
ABC
base types and mock interfaces. - Validates container for duplicate registrations, missing registrations and inconsistent scope registrations at runtime.
Table of Contents
- Class Setup (for Injectables)
- Constructor Setup (for accepting Injectables)
- Registration 3.1. Type Registration 3.2. Instance Registration 3.3. Lambda Registration (for decorators)
- Resolving 4.1. Lambda Registration with a Resolve 4.2. Resolve for application execution
- Validation
Class Setup (for Injectables)
In order for pyInjection to register and inject a class into a constructor, classes must extend a base class. This class can be an abstract class (using ABC) or a mock interface:
from abc import ABC, abstractmethod
class IFoo(ABC):
@abstractmethod
def do_something(self) -> None:
pass
or
class IFoo:
def do_something(self) -> None:
pass
Constructor Setup (for accepting Injectables)
In order for pyInjection to inject objects into class constructors, the constructor must be decorated with @Container.inject
:
from pjInjection import Container
class Bar:
__foo: IFoo
@Container.inject
def __init__(self, foo: IFoo):
self.__foo = foo
def run(self) -> None:
self.__foo.do_something()
Registration
pyInjection supports 3 types of injectable registration across both transient
and singleton
lifetimes.
from pyInjection import Container
Container.add_transient(interface= IFoo, implementation= Foo)
Container.add_singleton(interface= IBar, implementation= Bar)
Container registrations (like in .Net) maps an implementation
to the interface
base within supported constructors.
Type Registration:
Container.add_transient(interface= IFoo, implementation= Foo)
Instance Registration:
# Note this is registered as transient but will be resolved as a singleton
Container.add_transient(interface= IFoo, implementation= Foo())
Lambda Registration (for decorators):
Container.add_transient(interface= IFoo, implementation= lambda: Foo())
Resolving
In some cases you may wish to resolve an instance from the container (for a lambda function or running the application).
Lambda Registration with a Resolve
...
Container.add_transient(interface= IFoo, implementation= Foo)
Container.add_transient(
interface= IBar,
implementation= lambda: Bar(foo= Container.resolve(interface= IFoo)
)
Resolve for application execution
...
Container.add_singleton(interface= IFoo, implementation= Foo)
Container.add_singleton(interface= IBar, implementation= Bar)
bar: IBar = Container.resolve(interface= IBar)
bar.run()
Validation
In order to ensure that the container has been configured correctly and has everything necessary to build all injectable dependencies run the validate
method in the composition root:
...
Container.validate()
Any issues found within the container will be raised as an Exception. Exceptions will be raised for the following:
- Duplicate registrations
- Missing registrations
- Type registrations for constructors with primitive types (these should be an instance registration)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for pyInjection-1.0.10-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a7c893464f06841cd8479b4377052be7b2a1118560c50fb24f6e212f0ff024c3 |
|
MD5 | 272642bcf4b1e90a29bbb567bbf78a48 |
|
BLAKE2b-256 | 27d18b8bad0a8fd4cc2880d5be2502a936eac5ef68b4e03e46df1c6628ed0cd6 |