|
12 | 12 | from cq._core.dispatcher.base import BaseDispatcher, Dispatcher |
13 | 13 |
|
14 | 14 | type HandlerType[**P, T] = type[Handler[P, T]] |
15 | | -type HandlerFactory[**P, T] = Callable[..., Handler[P, T]] |
| 15 | +type HandlerFactory[**P, T] = Callable[..., Awaitable[Handler[P, T]]] |
16 | 16 |
|
17 | 17 | type Listener[T] = Callable[[T], Awaitable[Any]] |
18 | 18 |
|
@@ -46,24 +46,27 @@ class SubscriberDecorator[I, O]: |
46 | 46 | bus_type: BusType[I, O] | TypeAliasType | GenericAlias |
47 | 47 | injection_module: injection.Module = field(default_factory=injection.mod) |
48 | 48 |
|
49 | | - def __call__(self, first_input_type: type[I], /, *input_types: type[I]): # type: ignore[no-untyped-def] |
50 | | - def decorator(wrapped): # type: ignore[no-untyped-def] |
| 49 | + def __call__(self, first_input_type: type[I], /, *input_types: type[I]) -> Any: |
| 50 | + def decorator(wrapped: type[Handler[[I], O]]) -> type[Handler[[I], O]]: |
51 | 51 | if not isclass(wrapped) or not issubclass(wrapped, Handler): |
52 | 52 | raise TypeError(f"`{wrapped}` isn't a valid handler.") |
53 | 53 |
|
54 | | - bus = self.__find_bus() |
55 | | - factory = self.injection_module.make_injected_function(wrapped) |
| 54 | + bus = self.injection_module.find_instance(self.bus_type) |
| 55 | + lazy_instance = self.injection_module.aget_lazy_instance( |
| 56 | + wrapped, |
| 57 | + default=NotImplemented, |
| 58 | + ) |
| 59 | + |
| 60 | + async def getter() -> Handler[[I], O]: |
| 61 | + return await lazy_instance |
56 | 62 |
|
57 | 63 | for input_type in (first_input_type, *input_types): |
58 | | - bus.subscribe(input_type, factory) |
| 64 | + bus.subscribe(input_type, getter) |
59 | 65 |
|
60 | | - return wrapped |
| 66 | + return self.injection_module.injectable(wrapped) |
61 | 67 |
|
62 | 68 | return decorator |
63 | 69 |
|
64 | | - def __find_bus(self) -> Bus[I, O]: |
65 | | - return self.injection_module.find_instance(self.bus_type) |
66 | | - |
67 | 70 |
|
68 | 71 | class BaseBus[I, O](BaseDispatcher[I, O], Bus[I, O], ABC): |
69 | 72 | __slots__ = ("__listeners",) |
@@ -100,10 +103,8 @@ async def dispatch(self, input_value: I, /) -> O: |
100 | 103 | except KeyError: |
101 | 104 | return NotImplemented |
102 | 105 |
|
103 | | - return await self._invoke_with_middlewares( |
104 | | - handler_factory().handle, |
105 | | - input_value, |
106 | | - ) |
| 106 | + handler = await handler_factory() |
| 107 | + return await self._invoke_with_middlewares(handler.handle, input_value) |
107 | 108 |
|
108 | 109 | def subscribe(self, input_type: type[I], factory: HandlerFactory[[I], O]) -> Self: |
109 | 110 | if input_type in self.__handlers: |
@@ -132,13 +133,13 @@ async def dispatch(self, input_value: I, /) -> None: |
132 | 133 | return |
133 | 134 |
|
134 | 135 | await asyncio.gather( |
135 | | - *( |
| 136 | + *[ |
136 | 137 | self._invoke_with_middlewares( |
137 | | - handler_factory().handle, |
| 138 | + (await handler_factory()).handle, |
138 | 139 | input_value, |
139 | 140 | ) |
140 | 141 | for handler_factory in handler_factories |
141 | | - ) |
| 142 | + ] |
142 | 143 | ) |
143 | 144 |
|
144 | 145 | def subscribe( |
|
0 commit comments