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.7-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | bdbabdedfe01ca63169f09f9b3937217044346cc3196769f8684ede1a5624d04 |
|
MD5 | 1b7076b1feb4e25fbbef9863b870754f |
|
BLAKE2b-256 | 8928de746bfef0d368dc3ef688a7aaf66938f1309faa55fa8b8f964d814f165b |