Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Highly extensible Dependency Injection framework for humans
Project location: https://github.com/zibertscrem/hexdi
.. code:: bash
pip install hexdi
You should have python 3.5.* or higher
All of that usages you can find in examples directory
.. code:: python
import hexdi
class SomeA: def foo(self): pass
@hexdi.permanent(SomeA) class SomeAimplementation(SomeA): def foo(self): return 42
@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
.. code:: 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
.. code:: 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
.. code:: 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
.. code:: 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
If you have a project with separated base objects(to registration) and implementations(to injecting) there will be problematically to identify these implementations if you import it nowhere. For that situation, there is a class loading abstraction with a basic implementation that gets a list of specification objects with implementation modules. These specification object can be: - dot-separated module path as string: ‘pack1.pack2.module1’ - a function/lambda without params that returns a specification - a tuple that contains a function as a first argument and tuple of values as a second argument. Function should return a specification
.. code:: python
import hexdi from examples.multifile.interfaces import SomeA
loader = hexdi.get_loader([ 'examples.multifile.implementations' ])
@hexdi.inject(SomeA) def test(a: SomeA): print(a.foo())
if name == 'main': loader.load() test() # prints: 42
You also able to use recursive module finder to find all local packages, site-packages, dist-packages modules that contains type registering. Use same rules as module loader has
.. code:: python
import hexdi from examples.multifile.interfaces import SomeA
finder = hexdi.get_finder(['examples.multifile-finder']) loader = hexdi.get_loader(finder.find())
@hexdi.inject(SomeA) def test(a: SomeA): print(a.foo())
if name == 'main': loader.load() test() # prints: 69
FAQs
Highly extensible Dependency injection framework for humans
We found that hexdi demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.