Skip to main content

Dependency injection framework based on uber.fx for python

Project description

DInjections

This project implements a dependency injection framework in Python, based on uber's fx package.

It works as a modular dependency injection framework, where you can define provision of dependencies, using options pattern and hints to define which dependencies should be provided.

It also implements lifecycle management, where you can define hooks to be executed on start and stop.

Dependencies are only initialized when they are needed, even if provided.

Installation

pip install dinjections

Usage

from dinjections import App, Provide, Invoke, Hook, Lifecycle, Provider, Annotated, Annotations


# Define a class that will be injected
class Dependency0:
  pass

# Define a class that will be injected and has dependencies of the same type
class Dependency1:
  def __init__(self, d0_1: Annotated[Dependency0, Annotations(name="d0_1")], d0_2: Annotated[Dependency0, Annotations(name="d0_2")]):
    self.d0_1 = d0_1
    self.d0_2 = d0_2

  def run(self):
    print("Dependency1 running")

# Define another class that will be injected
class Dependency2:
    def __init__(self, d1: Dependency1):
        self.d1 = d1

    def run(self):
        self.d1.run()

# Function that returns a dependency
def new_dep_2(d1: Dependency1) -> Dependency2:
    return Dependency2()

# function that will be invoked
def register_hooks(l: Lifecycle, d: Dependency2):
    l.append_hook(Hook(
        on_start=lambda: {
            d.run()
        },
    ))

app = App(
    Provide(
        # dependency can be initiliazed passing it's class
        Dependency1,
        # and also with a function that returns the object
        new_dep_2,
        # you can also define a name for the dependency, in case there is more than one dependency of the same type
        Provider(Dependency0, name="d0_1"),
        Provider(Dependency0, name="d0_2"),
    ),
    Invoke(
        register_hooks,
    ))

app.run()

Dependencies of the same type

If you have dependencies of the same type, you can use the Provider class to define a name for the dependency with the name argument, and then use it to inject the dependency (as shown above).

If this is not done, a dependency will override the previous.

Dependency inheritance

If you have a dependency that inherits from another, you can use the Provider class to define the dependency with a name argument, and then use it to inject the dependency (as shown below).

# Define a class that will be injected
class TestClass4(TestClass3):
    pass

# expects a dependency of type TestClass3, but will accept TestClass4 named "t1"
def register_hooks(l: Lifecycle, t: TestClass3):
    l.append_hook(Hook(
        on_start=lambda: {
            t.run()
        },
    ))

app = App(
    Provide(
        # provides names dependency that inherites from expected class TestClass3
        Provider(TestClass4, name=TestClass3),
    ),
    Invoke(
        register_hooks,
    ))

app.run()

Grouped dependencies

You can group dependencies setting the group parameters to True in a Provider. This will make the dependency be injected as a list of dependencies, with all the dependencies that were provided with the same name.

class MyDependency:
    def __init__(self):

    def run(self):
        print("MyDependency running")

def register_hooks(l: Lifecycle, d: Annotated[MyDependency, Annotations(group=True)]):
    # d is now a list of MyDependency, with all the dependencies named "md" that were provided
    for t in d:
        l.append_hook(Hook(
            on_start=lambda: {
                t.run()
            },
        ))

app = App(
    Provide(
        Provider(MyDependency, group=True),
        Provider(MyDependency, group=True),
    ),
    Invoke(
        register_hooks,
    ))
app.run()

Lifecycle

You can define hooks to be executed on start and stop of the application.

Currently hooks are executed in the order they are defined, with no support for concurrency.

from dinjections import App, Hook, Lifecycle


def register_hooks(l: Lifecycle):
    l.append_hook(Hook(
        on_start=lambda: {
            print("Invoking 1")
        },
        on_stop=lambda: {
            print("Stopping 1")
        },
    ))
    l.append_hook(Hook(
        on_start=lambda: {
            print("Invoking 2")
        },
        on_stop=lambda: {
            print("Stopping 2")
        },
    ))

app = App(
    Invoke(
        register_hooks,
    )
)
app.run()

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

dinjections-1.1.1.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

dinjections-1.1.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file dinjections-1.1.1.tar.gz.

File metadata

  • Download URL: dinjections-1.1.1.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for dinjections-1.1.1.tar.gz
Algorithm Hash digest
SHA256 cfc8d6826c8fe1530acdda44fd378eca57f957c0ce88f8d1e0b745dab572fa42
MD5 5a6d0f7c58d7ed4ea4319fd1454071c9
BLAKE2b-256 0565657b16a7fc0a60ba8f5f877bd5383507a4b1d2c9ce7539dd19770488fa87

See more details on using hashes here.

File details

Details for the file dinjections-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: dinjections-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for dinjections-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e78ece1093a129114a35b543fe6abd5b3e0422f7c8c7f6fc5335160fcd246181
MD5 f13b00501919fd3044d6a52493aadc4d
BLAKE2b-256 5a9606238abf1e6a8ffd110942cf3a981fbf3c9fa3e1ba0308a4cee4f1582a32

See more details on using hashes here.

Supported by

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