Add container.py
parent
e90c709676
commit
0e473aa6eb
|
@ -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)
|
Loading…
Reference in New Issue