Skip to main content

Highly extensible Dependency injection framework for humans

Project description

# hexdi
Highly extensible Dependency Injection framework for humans

Project location: https://github.com/zibertscrem/hexdi

# Installation
```bash
pip install hexdi
```
You **should** have python 3.5.* or higher

# Usage

All of that usages you can find in **examples** directory

## Quick usage reference

```python
import hexdi


class SomeA:
def foo(self): pass


# mark that class as injectable with permanent lifetime for class SomeA
@hexdi.permanent(SomeA)
class SomeAimplementation(SomeA):
def foo(self):
return 42


# inject instance of SomeA as a first argument
@hexdi.inject(SomeA)
def test_injection(a: SomeA):
print('test_injection:', a.foo())


class ClassWithDependency:
# constructor injection
@hexdi.inject(SomeA)
def __init__(self, a: SomeA):
print('ClassWithDependency.__init__:', a.foo())

# after that we can use property like an instance of SomeA class
@property
@hexdi.dependency(SomeA)
def some_a(self) -> SomeA: pass

def foo(self):
print('ClassWithDependency.foo:', self.some_a.foo())

# method injection also works fine.
# Because injection members are passing after all transmitted positional arguments
@hexdi.inject(SomeA)
def foo_with_injection(self, a: SomeA):
print('ClassWithDependency.foo_with_injection:', a.foo())


if __name__ == '__main__':
# You don't need to provide any argument. DI container does it self
# There also should not be cycle dependencies due to lazy loading of any injections
test_injection() # prints: test_injection: 42
cwd = ClassWithDependency() # prints: ClassWithDependency.__init__: 42
cwd.foo() # prints: ClassWithDependency.foo: 42
cwd.foo_with_injection() # prints: ClassWithDependency.foo_with_injection: 42

```

## Self-binding

```python
import hexdi


@hexdi.permanent()
class SomeA:
def foo(self):
return 42


@hexdi.inject(SomeA)
def test(a):
print(a.foo())


if __name__ == '__main__':
test() # prints: 42

```

## Multiple injection arguments

```python
import hexdi


@hexdi.permanent()
class SomeA:
def foo(self):
return 42


@hexdi.permanent()
class SomeB:
def foo(self):
return 69


@hexdi.inject(SomeA, SomeB)
def test(a, b):
print(a.foo() + b.foo())


if __name__ == '__main__':
test() # prints: 111

```

## Permanent lifetime and transient lifetime

```python
import hexdi


@hexdi.permanent()
class SomeA:
NUMBER = 0

def __init__(self):
self.num = SomeA.NUMBER
SomeA.NUMBER += 1

def foo(self):
print(self.__class__.__name__, self.num)


@hexdi.transient()
class SomeB:
NUMBER = 0

def __init__(self):
self.num = SomeB.NUMBER
SomeB.NUMBER += 1

def foo(self):
print(self.__class__.__name__, self.num)


@hexdi.inject(SomeA)
def test_a(a):
a.foo()


@hexdi.inject(SomeB)
def test_b(b):
b.foo()


if __name__ == '__main__':
test_a() # prints: SomeA 0
test_a() # prints: SomeA 0
test_a() # prints: SomeA 0
test_b() # prints: SomeB 0
test_b() # prints: SomeB 1
test_b() # prints: SomeB 2

```

## Usage of container. Demonstration of lazy injection

```python
import hexdi


class SomeA:
def foo(self): pass


class SomeAImplementation(SomeA):
def foo(self):
return 42


@hexdi.permanent()
class SomeB:
def foo(self):
return 69


class SomeC:
def foo(self):
return 100500


@hexdi.inject(SomeC)
def test(c):
print(c.foo())


if __name__ == '__main__':
# getting of container
container = hexdi.get_root_container()
# binding SomeAImplementation on SomeA type with permanent lifetime
container.bind_type(SomeAImplementation, SomeA, hexdi.lifetime.PermanentLifeTimeManager)
instance = container.resolve(SomeA)
print(instance.foo()) # prints: 42
# resolve decorator-binded SomeB
instance = container.resolve(SomeB)
print(instance.foo()) # prints: 69
# bind SomeC on itself with permanent lifetime
container.bind_type(SomeC, SomeC, hexdi.lifetime.PermanentLifeTimeManager)
# we mark SomeC for injection above in test func,
# but all works fine, because it is lazy injection
test() # prints: 100500
```

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

hexdi-0.1.2b1.tar.gz (3.9 kB view details)

Uploaded Source

Built Distribution

hexdi-0.1.2b1-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file hexdi-0.1.2b1.tar.gz.

File metadata

  • Download URL: hexdi-0.1.2b1.tar.gz
  • Upload date:
  • Size: 3.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for hexdi-0.1.2b1.tar.gz
Algorithm Hash digest
SHA256 187dfcf9eeca823586311fb4d358c8bda96f1f3989a44cc5ac407ecb306b2559
MD5 5164f3985ee614e694bb9bc1bb2ab691
BLAKE2b-256 8f1d77699e926501000d6c782d18353b95731fca11c55f5047baef1ac34d96e0

See more details on using hashes here.

File details

Details for the file hexdi-0.1.2b1-py3-none-any.whl.

File metadata

File hashes

Hashes for hexdi-0.1.2b1-py3-none-any.whl
Algorithm Hash digest
SHA256 d9be736525bb2c184e1d3e2f895e9b505403f515340cfad2f6fc57ba464e48bb
MD5 bd7b6a0000611a896e97482ce29b0de7
BLAKE2b-256 b060d2a104bfa52428eda43915f44458f28903d4fea583c2dddfb70c7c7bc8bb

See more details on using hashes here.

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