Skip to main content

Implementation of dependency injection for Python 3

Project description

Build status pypi Test coverage

Implementation of dependency injection for Python 3

Features:

  • types resolution by signature types annotations (type hints)
  • types resolution by constructor parameter names and aliases (convention over configuration)
  • unintrusive: builds objects graph without the need to change classes source code (unlike some other Python implementations of dependency injection, like inject)
  • minimum overhead to obtain services, once the objects graph is built
  • support for singletons, transient and scoped services

This library is freely inspired by .NET Standard Microsoft.Extensions.DependencyInjection implementation (ref. MSDN, Dependency injection in ASP.NET Core, Using dependency injection in a .Net Core console application).

The idea of writing this library was strengthened by this article by Bob Gregory: Dependency Injection with Type Signatures in Python. Even before reading Gregory's article, I shared many of the ideas he described in his blog.

Installation

pip install rodi

De gustibus non disputandum est

This library is designed to work both by type hints in constructor signatures, and by constructor parameter names (convention over configuration), like described in below diagram. It can be useful for those who like type hinting, those who don't, and those who like having both options.

Usage option

Minimum overhead

rodi works by inspecting __init__ methods once at runtime, to generate functions that return instances of desired types. Validation steps, for example to detect circular dependencies or missing services, are done when building these functions, so additional validation is not needed when activating services.

For this reason, services are first registered inside an instance of Container class, which implements a method build_provider() that returns an instance of Services. The service provider is then used to obtain desired services by type or name. Inspection and validation steps are done only when creating an instance of service provider.

Classes

In the example below, a singleton is registered by exact instance.

container = Container()
container.add_instance(Cat("Celine"))

services = container.build_provider()  # --> validation, generation of functions

cat = services.get(Cat)

assert cat is not None
assert cat.name == "Celine"

Service life style:

  • singleton - instantiated only once per service provider
  • transient - services are instantiated every time they are required
  • scoped - instantiated only once per service resolution (root call, e.g. once per web request)

Documentation

For documentation and examples, please refer to the wiki in GitHub, https://github.com/RobertoPrevato/rodi/wiki.


Develop and run tests locally

pip install -r dev_requirements.txt

# run tests using automatic discovery:
pytest

Public project in Azure DevOps

https://dev.azure.com/robertoprevato/rodi - see here the project in Azure DevOps, with builds and other goodness.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rodi-1.0.5.tar.gz (10.0 kB view hashes)

Uploaded Source

Built Distribution

rodi-1.0.5-py3-none-any.whl (8.6 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page