Finistere / antidote

Dependency injection for Python
MIT License
90 stars 9 forks source link

Improved lazy, replacing parameterized & @factory ? #42

Closed Finistere closed 2 years ago

Finistere commented 2 years ago

Current @factory allows one to declare external dependencies and parameterized to customize dependencies. Both could be replaced with an improved @lazy which could be used as a marker like inject.me().

To replace a @factory function:

from antidote import lazy, inject
from redis import Redis

@lazy
def current_redis() -> Redis:
    return Redis()

@inject
def f(redis: Redis = current_redis()):
    ...

To replace a @factory class:

from antidote import lazy, inject, service
from redis import Redis

@service
class RedisFactory:
    def create(self) -> Redis:
        ...

@lazy
def current_redis(factory: RedisFactory = inject.me()) -> Redis:
    return factory.create()

@inject
def f(redis: Redis = current_redis()):
    ...

To replace parameterized():

from antidote import lazy, inject, service
from dataclasses import dataclass

@dataclass
class TemporaryDirectory:
    path: str

@lazy(singleton=False)
def tmp_dir(prefix: str) -> TemporaryDirectory:
    return TemporaryDirectory(path="...")

@inject
def f(dir: TemporaryDirectory = tmp_dir(prefix='f_')):
    ...

Injections could be hidden easily with:

def current_redis() -> Redis:
    return _current_redis()

@lazy
def _current_redis(factory: RedisFactory = inject.me()) -> Redis:
    return factory.create()