37
37
)
38
38
39
39
from injection .common .event import Event , EventChannel , EventListener
40
+ from injection .common .invertible import Invertible , SimpleInvertible
40
41
from injection .common .lazy import Lazy , LazyMapping
41
42
from injection .common .queue import LimitedQueue
42
43
from injection .common .tools .threading import synchronized
@@ -157,6 +158,13 @@ def get_instance(self) -> _T:
157
158
raise NotImplementedError
158
159
159
160
161
+ class FallbackInjectable (Injectable [_T ], ABC ):
162
+ __slots__ = ()
163
+
164
+ def __bool__ (self ) -> bool :
165
+ return False
166
+
167
+
160
168
@dataclass (repr = False , frozen = True , slots = True )
161
169
class BaseInjectable (Injectable [_T ], ABC ):
162
170
factory : Callable [[], _T ]
@@ -197,12 +205,9 @@ def get_instance(self) -> _T:
197
205
198
206
199
207
@dataclass (repr = False , frozen = True , slots = True )
200
- class ShouldBeInjectable (Injectable [_T ]):
208
+ class ShouldBeInjectable (FallbackInjectable [_T ]):
201
209
cls : type [_T ]
202
210
203
- def __bool__ (self ) -> bool :
204
- return False
205
-
206
211
def get_instance (self ) -> NoReturn :
207
212
raise InjectionError (f"`{ format_type (self .cls )} ` should be an injectable." )
208
213
@@ -260,28 +265,28 @@ def is_locked(self) -> bool:
260
265
261
266
@property
262
267
def __classes (self ) -> frozenset [type ]:
263
- return frozenset (self .__data . keys () )
268
+ return frozenset (self .__data )
264
269
265
270
@property
266
271
def __injectables (self ) -> frozenset [Injectable ]:
267
272
return frozenset (self .__data .values ())
268
273
274
+ @synchronized ()
269
275
def update (self , classes : Iterable [type ], injectable : Injectable , override : bool ):
270
276
classes = frozenset (get_origins (* classes ))
271
277
272
- with synchronized ():
273
- if not injectable :
274
- classes -= self .__classes
275
- override = True
278
+ if not injectable :
279
+ classes -= self .__classes
280
+ override = True
276
281
277
- if classes :
278
- event = ContainerDependenciesUpdated (self , classes , override )
282
+ if classes :
283
+ event = ContainerDependenciesUpdated (self , classes , override )
279
284
280
- with self .notify (event ):
281
- if not override :
282
- self .__check_if_exists (classes )
285
+ with self .notify (event ):
286
+ if not override :
287
+ self .__check_if_exists (classes )
283
288
284
- self .__data .update ((cls , injectable ) for cls in classes )
289
+ self .__data .update ((cls , injectable ) for cls in classes )
285
290
286
291
return self
287
292
@@ -290,6 +295,8 @@ def unlock(self):
290
295
for injectable in self .__injectables :
291
296
injectable .unlock ()
292
297
298
+ return self
299
+
293
300
def add_listener (self , listener : EventListener ):
294
301
self .__channel .add_listener (listener )
295
302
return self
@@ -438,8 +445,17 @@ def get_instance(self, cls: type[_T], none: bool = True) -> _T | None:
438
445
instance = injectable .get_instance ()
439
446
return cast (cls , instance )
440
447
441
- def get_lazy_instance (self , cls : type [_T ]) -> Lazy [_T | None ]:
442
- return Lazy (lambda : self .get_instance (cls ))
448
+ def get_lazy_instance (
449
+ self ,
450
+ cls : type [_T ],
451
+ cache : bool = False ,
452
+ ) -> Invertible [_T | None ]:
453
+ if cache :
454
+ return Lazy (lambda : self .get_instance (cls ))
455
+
456
+ function = self .inject (lambda instance = None : instance )
457
+ function .set_owner (cls )
458
+ return SimpleInvertible (function )
443
459
444
460
def update (
445
461
self ,
@@ -503,6 +519,8 @@ def unlock(self):
503
519
for broker in self .__brokers :
504
520
broker .unlock ()
505
521
522
+ return self
523
+
506
524
def add_listener (self , listener : EventListener ):
507
525
self .__channel .add_listener (listener )
508
526
return self
@@ -661,15 +679,7 @@ def __get__(self, instance: object = None, owner: type = None):
661
679
return self .__wrapper .__get__ (instance , owner )
662
680
663
681
def __set_name__ (self , owner : type , name : str ):
664
- if self .__dependencies .are_resolved :
665
- raise TypeError (
666
- "Function owner must be assigned before dependencies are resolved."
667
- )
668
-
669
- if self .__owner :
670
- raise TypeError ("Function owner is already defined." )
671
-
672
- self .__owner = owner
682
+ self .set_owner (owner )
673
683
674
684
@property
675
685
def signature (self ) -> Signature :
@@ -692,14 +702,21 @@ def bind(
692
702
)
693
703
return Arguments (bound .args , bound .kwargs )
694
704
695
- def update (self , module : Module ):
696
- with synchronized ():
697
- self .__dependencies = Dependencies .resolve (
698
- self .signature ,
699
- module ,
700
- self .__owner ,
705
+ def set_owner (self , owner : type ):
706
+ if self .__dependencies .are_resolved :
707
+ raise TypeError (
708
+ "Function owner must be assigned before dependencies are resolved."
701
709
)
702
710
711
+ if self .__owner :
712
+ raise TypeError ("Function owner is already defined." )
713
+
714
+ self .__owner = owner
715
+ return self
716
+
717
+ @synchronized ()
718
+ def update (self , module : Module ):
719
+ self .__dependencies = Dependencies .resolve (self .signature , module , self .__owner )
703
720
return self
704
721
705
722
def on_setup (self , wrapped : Callable [[], Any ] = None , / ):
0 commit comments