Skip to content

Commit 684f601

Browse files
committed
✨ Added dynamic dependency injection
1 parent 0dacedc commit 684f601

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Pymediator
22

3+
[![downloads](https://img.shields.io/pypi/dm/django-smooth-migrations.svg)](https://pypistats.org/packages/pymediator)
4+
[![versions](https://img.shields.io/pypi/pyversions/pymediator.svg)](https://pypi.python.org/pypi/pymediator)
5+
[![license](https://img.shields.io/github/license/serivt/pymediator.svg)](https://github.com/serivt/pymediator/blob/master/LICENSE)
6+
37
Provides a lightweight and extensible implementation of the Mediator pattern in Python, specifically designed for systems that follow the CQRS (Command Query Responsibility Segregation) pattern. Its architecture allows for a clear separation of command and query logic, making it ideal for clean architectures and event-driven systems.
48

59
## Install

pymediator/mediator.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABC, abstractmethod
2-
from typing import Any
2+
from typing import Any, Type, get_type_hints
33

44
from pymediator.exceptions import HandlerProtocolViolationException
55
from pymediator.handlers import Handler, Request
@@ -57,7 +57,12 @@ def inject(self, **kwargs) -> "Mediator": # type: ignore[no-untyped-def]
5757
return Mediator(registry=self.registry, dependencies=kwargs)
5858

5959
def send(self, request: Request) -> Any:
60-
handler: Handler = self._registry.get_handler(request)(**self._dependencies)
60+
handler_type: Type[Handler] = self._registry.get_handler(request)
61+
local_dependencies: dict = {}
62+
for name, instance in get_type_hints(handler_type.__init__).items():
63+
if name in self._dependencies:
64+
local_dependencies[name] = self._dependencies[name]
65+
handler: Handler = handler_type(**local_dependencies)
6166
if not isinstance(handler, Handler):
6267
raise HandlerProtocolViolationException(handler.__class__.__name__)
6368
return handler.handle(request)

tests/test_mediators.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,45 @@ def handle(self, request: SumRequest) -> int:
6060
mediator: Mediator = Mediator(registry=registry)
6161
response: int = mediator.inject(sum_utils=SumUtils()).send(SumRequest(x=3, y=5))
6262
assert response == 8
63+
64+
def test_injection_multiple(self) -> None:
65+
class SumUtils:
66+
def sum(self, x: int, y: int) -> int:
67+
return x + y
68+
69+
class MultiplyUtils:
70+
def multiply(self, x: int, y: int) -> int:
71+
return x * y
72+
73+
@dataclass
74+
class SumRequest:
75+
x: int
76+
y: int
77+
78+
class SumHandler:
79+
def __init__(self, sum_utils: SumUtils) -> None:
80+
self._sum_utils: SumUtils = sum_utils
81+
82+
def handle(self, request: SumRequest) -> int:
83+
return self._sum_utils.sum(request.x, request.y)
84+
85+
@dataclass
86+
class MultiplyRequest:
87+
x: int
88+
y: int
89+
90+
class MultiplyHandler:
91+
def __init__(self, multiply_utils: MultiplyUtils) -> None:
92+
self._multiply_utils: MultiplyUtils = multiply_utils
93+
94+
def handle(self, request: MultiplyRequest) -> int:
95+
return self._multiply_utils.multiply(request.x, request.y)
96+
97+
registry: InstanceRegistry = InstanceRegistry()
98+
registry.register(SumRequest, SumHandler)
99+
registry.register(MultiplyRequest, MultiplyHandler)
100+
mediator: Mediator = Mediator(registry=registry).inject(
101+
sum_utils=SumUtils(), multiply_utils=MultiplyUtils()
102+
)
103+
assert mediator.send(SumRequest(x=3, y=5)) == 8
104+
assert mediator.send(MultiplyRequest(x=3, y=5)) == 15

0 commit comments

Comments
 (0)