68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
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) |