melobot.di¶
依赖注入部件¶
- class melobot.di.Depends[源代码]¶
基类:
Generic[T,U]- __init__(dep: SyncOrAsyncCallable[(), Any] | Depends[Any], sub_getter: SyncOrAsyncCallable[typing_extensions.Any, Any] | None = None, cache: bool = False, recursive: bool = True) None[源代码]¶
初始化一个依赖项
- 参数:
dep (SyncOrAsyncCallable[(), Any] | Depends[Any]) -- 依赖来源(可调用对象,异步可调用对象,或依赖项)
sub_getter (SyncOrAsyncCallable[(typing_extensions.Any,), Any] | None) -- 子获取器(可调用对象,异步可调用对象或空),在获得依赖之后,于其上继续获取
cache (bool) -- 是否启用缓存
recursive (bool) -- 是否启用递归满足(默认启用,如果 dep 和 sub_getter 为可调用对象,会自动被 {func}`.inject_deps` 装饰;关闭可节约性能)
- 返回类型:
None
- class melobot.di.CbDepends[源代码]¶
基类:
Depends,BetterABC,Generic[T]回调型依赖
依赖项,但在依赖满足后,执行内部的回调
- __init__(dep: SyncOrAsyncCallable[(), Any], cache: bool = False, recursive: bool = False) None[源代码]¶
- 参数:
dep (SyncOrAsyncCallable[(), Any])
cache (bool)
recursive (bool)
- 返回类型:
None
- melobot.di.inject_deps(injectee: SyncOrAsyncCallable[..., T], manual_arg: bool = False, avoid_repeat: bool = False) AsyncCallable[..., T][源代码]¶
依赖注入标记装饰器,标记当前对象需要被依赖注入
可以标记的对象类别有: 同步函数,异步函数,匿名函数,同步生成器函数,异步生成器函数,实例方法、类方法、静态方法
- 参数:
injectee (SyncOrAsyncCallable[..., T]) -- 需要被注入的对象
manual_arg (bool) -- 当前对象标记需要依赖注入后,是否还可以给某些参数手动传参
avoid_repeat (bool) -- 是否避免在多层装饰时重复注入。检查内层装饰链,若内层装饰已有注入则放弃本次注入。 但需要所有内层装饰使用
functools.wraps()进行包装,否则无法检测
- 返回:
异步可调用对象,但保留原始参数和返回值签名
- 返回类型:
AsyncCallable[..., T]
依赖注入元数据标记¶
依赖注入时用作 Annotated 元数据,只能对自动依赖使用。也就是说不能和 Depends 同时放在 Annotated 中。
- class melobot.di.Exclude[源代码]¶
基类:
object数据类。types 指定的类别会在依赖注入时被排除
# 假设有 B 继承于 A, C 继承于 A, D 继承于 A # 表示不包括 B 和 C 类别的 A 的所有子类型: NewTypeHint = Annotated[A, Exclude(types=[B, C])] # 当然,依然会兼容 A 类型
- class melobot.di.Reflect[源代码]¶
基类:
object数据类。指定不直接获取当前依赖项,而是获取对应的一个反射代理
这适用于希望依赖会随着上下文改变,而动态变化的情况。例如动态引用会话流程中的事件对象
# 注入一个依赖时进一步包装为反射依赖 ReflectedEvent = Annotated[Event, Reflect()] event_proxy: RefelectedEvent # 就像使用 event 一样使用 event_proxy event_proxy.attr_xxx event_proxy.method_xxx() # 不过 event_proxy 不是完美的代理 # 因此 isinstance 类似的操作,使用 __origin__ 获取原始对象 isinstance(event_proxy.__origin__, SomeEventType) # 或者是作为运行逻辑未知的函数的参数 dont_know_what_this_do(event_proxy.__origin__)
- class melobot.di.MatchEvent[源代码]¶
基类:
object数据类。指定从当前事件的上下文中获取依赖
默认情况下,获取 Adapter 依赖都会直接尝试遍历所有可能的对象。
即尽最大可能获取指定类型的对象。但有时需要实现这样的需求:
# 假设 bot 已经加载了两个适配器:ObAdapter 和 XxAdapter from melobot.handle import on_event # 期待事件来自 ObAdapter 时,调用这个 @on_event() async def on_onebot_event(adapter: ObAdapter) -> None: ... # 期待事件来自 XxAdapter 时,调用这个 @on_event() async def on_xx_event(adapter: XxAdapter) -> None: ... # 但默认的逻辑是:bot 只要加载了对应的适配器,依赖就可以满足 # 所以实际上他们都会被调用,没有任何区分效果 # 使用 MatchEvent 来改变依赖获取的逻辑: # 事件的来源适配器必须和 MatchEvent 中指定的类型匹配,依赖才能满足 @on_event() async def on_onebot_event(adapter: Annotated[ObAdapter, MatchEvent()]) -> None: ... @on_event() async def on_xx_event(adapter: Annotated[XxAdapter, MatchEvent()]) -> None: ...