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