-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontainer.py
More file actions
51 lines (39 loc) · 1.67 KB
/
container.py
File metadata and controls
51 lines (39 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from functools import wraps
from typing import TypeVar, Callable, Dict, Optional, Type, TYPE_CHECKING, Any
from sfr.exceptions import AnnotationsException
_T = TypeVar("_T")
if TYPE_CHECKING:
import builtins
class Container(object):
factory_fn: Dict[Type[_T], Callable[..., Type[_T]]] = {}
object_map: Dict[Type[_T], _T] = {}
def __init__(self) -> None:
pass
@classmethod
def get(cls, obj_type: Type[_T]) -> _T:
obj = cls.object_map.get(obj_type)
if obj is None:
obj = cls.factory_fn.get(obj_type)()
cls.object_map.update({obj_type: obj})
return obj
@classmethod
def factory(cls, *, name: Optional[str] = None, options: Any = None):
"""装饰器,用此装饰器装饰的工厂函数会被注册的容器内部
被装饰的工厂函数必须标明返回的类型
>>> @Contaier.factory()
def mysql_factory(mysql_info:str)->Mysql:
return Mysql(mysql_info)
Args:
name (Optional[str], optional): 定义工厂返回的对象别名,如果不传,则在注入的时候根据函数参数的注解自动注入. Defaults to None.
options (Any, optional): 初始化的参数. Defaults to None.
"""
def decorator(fn: Callable[..., Type[_T]]):
return_type = fn.__annotations__['return']
if return_type == type(None):
raise AnnotationsException("工厂函数必须标注返回对象类型")
cls.factory_fn.update({return_type: fn})
@wraps
def inner(fn):
return fn()
return inner
return decorator