Add container.py

main
ado 2023-10-11 09:52:38 -04:00
parent e90c709676
commit 0e473aa6eb
1 changed files with 68 additions and 0 deletions

68
container.py Normal file
View File

@ -0,0 +1,68 @@
from dataclasses import dataclass
from types import LambdaType, FunctionType
from typing import Mapping, Type, TypeVar
T = TypeVar("T")
class ServiceLookupException(Exception):
pass
@dataclass
class ServiceContainer:
_singletons: Mapping[str, T]
_factories: Mapping[str, T]
def register_name(self, name: str, instance: T) -> None:
if type(instance) is LambdaType or type(instance) is FunctionType:
self._factories[name] = instance
else:
self._singletons[name] = instance
def retrieve_name(self, name: str, _: Type[T]) -> T:
if name in self._singletons:
return self._singletons[name]
elif name in self._factories:
return self._factories[name]()
raise ServiceLookupException(f"Could not locate service with name {name}")
def register_type(self, instance: T) -> None:
t = type(instance)
name = str(Type[t])
if type(instance) is LambdaType or type(instance) is FunctionType:
self._factories[name] = instance
else:
self._singletons[name] = instance
def retrieve_type(self, desired_type: Type[T]) -> T:
name = str(desired_type)
if name in self._singletons:
return self._singletons[name]
elif name in self._factories:
return self._factories[name]()
raise ServiceLookupException(f"Could not locate service with name {name}")
@dataclass
class Foo:
bar: str
def __post_init__(self):
print(f"Initialized with {self.bar}")
container = ServiceContainer({}, {})
container.register_name("foo_lam", lambda : Foo("bar"))
foo_single = Foo("baz")
container.register_name("foo_single", foo_single)
mc1 = container.retrieve_name("foo_lam", Type[Foo])
mc2 = container.retrieve_name("foo_lam", Type[Foo])
mc3 = container.retrieve_name("foo_single", Type[Foo])
mc4 = container.retrieve_name("foo_single", Type[Foo])
print(mc1.bar)
print(mc2.bar)
print(mc3.bar)
print(mc4.bar)