transient.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # -*- coding: utf-8 -*-
  2. """
  3. Transient-Scope für Services.
  4. Erstellt bei jedem Abruf eine neue Instanz.
  5. """
  6. from __future__ import annotations
  7. from typing import Callable, Generic, TypeVar
  8. from trixy_core.service.scopes.scope import ServiceScope, ScopeType
  9. T = TypeVar("T")
  10. class TransientScope(ServiceScope[T], Generic[T]):
  11. """
  12. Transient-Scope für Services.
  13. Jeder Abruf erstellt eine neue Instanz. Keine Instanzen
  14. werden gecacht.
  15. Example:
  16. scope = TransientScope(lambda: MyService())
  17. instance1 = scope.get_instance("my_service")
  18. instance2 = scope.get_instance("my_service")
  19. assert instance1 is not instance2
  20. """
  21. scope_type = ScopeType.TRANSIENT
  22. def __init__(
  23. self,
  24. factory: Callable[[], T],
  25. track_instances: bool = False,
  26. ) -> None:
  27. """
  28. Initialisiert den Transient-Scope.
  29. Args:
  30. factory: Factory-Funktion zur Instanz-Erstellung.
  31. track_instances: Ob erstellte Instanzen getrackt werden sollen.
  32. """
  33. super().__init__(factory)
  34. self._track_instances = track_instances
  35. self._instances: list[T] = []
  36. self._instance_count = 0
  37. @property
  38. def instance_count(self) -> int:
  39. """Anzahl der erstellten Instanzen."""
  40. return self._instance_count
  41. def get_instance(self, key: str) -> T:
  42. """
  43. Erstellt eine neue Instanz.
  44. Args:
  45. key: Service-Schlüssel (wird nicht verwendet).
  46. Returns:
  47. Neue Service-Instanz.
  48. """
  49. instance = self._factory()
  50. self._instance_count += 1
  51. if self._track_instances:
  52. self._instances.append(instance)
  53. return instance
  54. def dispose(self) -> None:
  55. """Disposed alle getrackten Instanzen."""
  56. for instance in self._instances:
  57. if hasattr(instance, "dispose"):
  58. try:
  59. instance.dispose()
  60. except Exception:
  61. pass
  62. elif hasattr(instance, "close"):
  63. try:
  64. instance.close()
  65. except Exception:
  66. pass
  67. self._instances.clear()
  68. def get_tracked_instances(self) -> list[T]:
  69. """
  70. Gibt alle getrackten Instanzen zurück.
  71. Returns:
  72. Liste der Instanzen (leer wenn tracking deaktiviert).
  73. """
  74. return list(self._instances)