All Projects → teamhide → pythondi

teamhide / pythondi

Licence: Apache-2.0 License
Python lightweight dependency injection library

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pythondi

iocgo
A lightweight Inversion of Control (IoC) (Dependency Injection) container for Golang
Stars: ✭ 36 (+38.46%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
Kangaru
🦘 A dependency injection container for C++11, C++14 and later
Stars: ✭ 297 (+1042.31%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
ThunderboltIoc
One of the very first IoC frameworks for .Net that has no reflection. An IoC that casts its services before thunder casts its bolts.
Stars: ✭ 40 (+53.85%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
Singularity
A extremely fast ioc container for high performance applications
Stars: ✭ 63 (+142.31%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
Ioc
🦄 lightweight (<1kb) inversion of control javascript library for dependency injection written in typescript
Stars: ✭ 171 (+557.69%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
React Ioc
Hierarchical Dependency Injection with new React 16 Context API
Stars: ✭ 133 (+411.54%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
Swinject
Dependency injection framework for Swift with iOS/macOS/Linux
Stars: ✭ 4,958 (+18969.23%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
Typhoon
Powerful dependency injection for Objective-C ✨✨ (https://PILGRIM.PH is the pure Swift successor to Typhoon!!)✨✨
Stars: ✭ 2,711 (+10326.92%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
vesselize
⛵ A JavaScript IoC container that works seamlessly with Vue.js and React.
Stars: ✭ 22 (-15.38%)
Mutual labels:  dependency-injection, inversion-of-control, ioc-container
diod
A very opinionated inversion of control (IoC) container and dependency injector for Typescript, Node.js or browser apps.
Stars: ✭ 36 (+38.46%)
Mutual labels:  dependency-injection, inversion-of-control
di
Simple and yet powerful Dependency Injection for Go
Stars: ✭ 188 (+623.08%)
Mutual labels:  dependency-injection, inversion-of-control
AzureFunctions.Extensions
This provides some useful extensions for Azure Functions.
Stars: ✭ 81 (+211.54%)
Mutual labels:  dependency-injection, ioc-container
DependencyInjector
Lightweight dependency injector
Stars: ✭ 30 (+15.38%)
Mutual labels:  dependency-injection, ioc-container
di
🛠 A full-featured dependency injection container for go programming language.
Stars: ✭ 156 (+500%)
Mutual labels:  dependency-injection, ioc-container
inversify-koa-utils
inversify-koa-utils is a module based on inversify-express-utils. This module has utilities for koa 2 applications development using decorators and IoC Dependency Injection (with inversify)
Stars: ✭ 27 (+3.85%)
Mutual labels:  dependency-injection, inversion-of-control
inject
[Archived] See https://github.com/goava/di.
Stars: ✭ 49 (+88.46%)
Mutual labels:  dependency-injection, ioc-container
Griffin.Container
Inversion of control container with (almost) zero configuration
Stars: ✭ 13 (-50%)
Mutual labels:  dependency-injection, inversion-of-control
SwiftInjection
Dependency Injection framework for Swift
Stars: ✭ 21 (-19.23%)
Mutual labels:  dependency-injection, ioc-container
vue-ioc
IoC and DI for Vue powered by InversifyJS and inspired by Angular Module syntactic sugar.
Stars: ✭ 39 (+50%)
Mutual labels:  dependency-injection, inversion-of-control
siringa
Minimalist dependency injection library for Python that embraces type annotations syntax
Stars: ✭ 51 (+96.15%)
Mutual labels:  dependency-injection, inversion-of-control

pythondi

license pypi pyversions Downloads


pythondi is a lightweight dependency injection library for python

Support both sync and async functions

Installation

pip3 install pythondi

Usage

First, you have to binding classes to provider.

There is three different ways to binding.

  • Binding one by one
from pythondi import Provider


provider = Provider()
provider.bind(Repo, SQLRepo)
provider.bind(Usecase, CreateUsecase)
  • Binding at initialization
from pythondi import Provider


provider = Provider(cls=Repo, new_cls=SQLRepo)
  • Binding at initialization with dictionary
from pythondi import Provider


provider = Provider(classes={Repo: SQLRepo, Usecase: CreateUsecase})

After binding, you need to configure it to container

from pythondi import configure, configure_after_clear


# Inject with configure
configure(provider=provider)

# Or if you want to fresh inject, use `configure_after_clear`
configure_after_clear(provider=provider)

Import inject

from pythondi import inject

Add type annotations that you want to inject dependencies

class Usecase:
    def __init__(self, repo: Repo):
        self.repo = repo

Add decorator

class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo

Initialize class with no arguments

usecase = Usecase()

Or, you can also inject manually through decorator arguments

class Usecase:
    @inject(repo=SQLRepo)
    def __init__(self, repo):
        self.repo = repo

In this case, do not have to configure providers and type annotation.

For test

In case of test codes, you probably want to use mock objects.

In that case, you must use keyword arguments.

class MockRepo:
    pass


@inject()
def test(repo: Repo):
    return repo

Yes:

test(repo=MockRepo())

No:

test(MockRepo())
test(MockRepo)

Note

At the moment of inject, class is automatically initialized.

So you don't have to initialize your class inside of code.

Yes:

@inject()
def __init__(self, repo: Repo):
    self.repo = repo

No:

@inject()
def __init__(self, repo: Repo):
    self.repo = repo()

General example

import abc

from pythondi import Provider, configure, configure_after_clear, inject


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def get(self):
        print('SQLRepo')


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


if __name__ == '__main__':
    # Init provider
    provider = Provider()

    # Bind `Impl` class to `Interface` class
    provider.bind(Repo, SQLRepo)

    # Inject with configure
    configure(provider=provider)

    # Or if you want to fresh injection, use `configure_after_clear`
    configure_after_clear(provider=provider)

    # Init class without arguments
    u = Usecase()

FastAPI example

from fastapi import FastAPI, APIRouter

from pythondi import Provider, configure, inject
import abc

router = APIRouter()


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


@router.route('/')
def home():
    usecase = Usecase()
    usecase.repo.get()
    return {'hello': 'world'}


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = FastAPI()
    app.include_router(router)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Flask example

from flask import Flask, Blueprint, jsonify

from pythondi import Provider, configure, inject
import abc

bp = Blueprint('home', __name__)


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


@bp.route('/')
def home():
    usecase = Usecase()
    usecase.repo.get()
    return jsonify({'hello': 'world'})


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = Flask(__name__)
    app.register_blueprint(bp)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Sanic example

import abc

from sanic import Sanic, Blueprint
from sanic.response import json

from pythondi import Provider, configure, inject


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


bp = Blueprint('home', url_prefix='/')


@bp.route('/')
async def home(request):
    usecase = Usecase()
    usecase.repo.get()
    return json({'hello': 'world'})


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = Sanic(__name__)
    app.blueprint(bp)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Django example

"""
In case of django, just put the initializing code inside of django startup

You can use project folder's __init__.py or urls.py
"""
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].