A decorator-based dependency injection tool.
Project description
Kiwi-DI
A decorator-based dependency injection library.
Quick Start
Basic Usage
Decorate a class with @comoponent, then it will be registered and instantiated as a singleton,
and you can use it everywhere.
# ------------------- flowers.py -----------------------
from kiwi_di import component
@component
class Rose:
...
@component
class Tulip:
...
If a class depends on some other classes, it can be instantiated as singleton if all of its constructor parameter are either:
- of the type that is decorated with
@component, like theRoseandTulip. - has a default value, like the
Sunflower
# ------------------- garden.py -----------------------
from kiwi_di import component
from flowers import Rose, Tulip
class Sunflower:
pass
@component
class Garden:
def __init__(self, rose: Rose, tulip: Tulip, sunflower: Sunflower = Sunflower()):
self.rose = rose
self.tulip = tulip
self.sunflower = sunflower
You can use @inject to inject the instances of registered classes to the wherever they are needed.
# ------------------- main.py -----------------------
from kiwi_di import inject
from garden import Garden
@inject
def main(my_garden: Garden):
print(my_garden.rose)
print(my_garden.tulip)
print(my_garden.sunflower)
if __name__ == '__main__':
# No need to pass any arguments
main()
# Output:
# <flowers.Rose object at 0x00000260B6D29310>
# <flowers.Tulip object at 0x00000260B6D29280>
# <garden.Sunflower object at 0x000001DBFBA30440>
Use @named_component to handle inheritance
You can use the decorator @named_component to create different instances of the same superclass.
In the example below, two instances of the class Animal will be created, each with a specific qualifier.
# ------------------- animal.py -----------------------
import abc
from typing import override
from kiwi_di import named_component
class Animal(abc.ABC):
@abc.abstractmethod
def greeting(self) -> str: ...
@named_component(qualifier="cat")
class Cat(Animal):
@override
def greeting(self) -> str:
return "Hello, I'm a cat."
@named_component(qualifier="dog")
class Dog(Animal):
@override
def greeting(self) -> str:
return "Hello, I'm a dog."
When injecting these instance, use Qualifier to specify which instance you want.
# ------------------- animal_family.py -----------------------
from typing import Annotated
from kiwi_di import component, Qualifier
from animal import Animal
@component
class AnimalFamily:
def __init__(
self,
cat: Annotated[Animal, Qualifier("cat")],
dog: Annotated[Animal, Qualifier("dog")],
):
self.cat = cat
self.dog = dog
Check the output.
# ------------------- main.py -----------------------
from animal import AnimalFamily
from kiwi_di import inject
@inject
def main(animal_family: AnimalFamily):
print(animal_family.dog)
print(animal_family.cat)
if __name__ == '__main__':
main()
# Output:
# <animal.Dog object at 0x000001AD33900710>
# <animal.Cat object at 0x000001AD33900440>
About the decorated classes & functions
Classes
If a class is decorated with @component or @named_component:
- You can still instantiate the class in the normal way:
animal_family = AnimalFamily(cat=Cat(), dog=Dog())
# <__main__.AnimalFamily object at 0x0000022D88BDC230>
- It still has its original type:
print(AnimalFamily.__name__)
# Output: AnimalFamily
animal_family = AnimalFamily(cat=Cat(), dog=Dog())
print(isinstance(animal_family, AnimalFamily))
# Output: True
Functions
If a function is decorated with @inject, its signature will be changed:
- It will become a function that takes no arguments.
- Its return type will not be changed.
It's not recommended to decorate a function with
@componentor@named_component, the behaviour of which is undefined and not the purpose of these decorators.
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kiwi_di-0.1.1.tar.gz.
File metadata
- Download URL: kiwi_di-0.1.1.tar.gz
- Upload date:
- Size: 7.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61ccd1005037480c1022b9c119f9ee41a658fe54c9fa6973ae146ad2ee4dc8f7
|
|
| MD5 |
90542e79b5916874115167941909d30d
|
|
| BLAKE2b-256 |
d1c6f37bb113860bcec9403ca59b959ba98b7886385d3f6d97744fc2602fb1b3
|
File details
Details for the file kiwi_di-0.1.1-py3-none-any.whl.
File metadata
- Download URL: kiwi_di-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09a716ad59f656f21d4cd8ee0527b65f4eb7d88efcc611b08c42d9c278eed3de
|
|
| MD5 |
3a9ceb348dff353ef056988188245409
|
|
| BLAKE2b-256 |
9610b4ab4cb19ef78ef273eff9d4db0aa49b32cbf691516a069d4880967e19b3
|