基于类型提示的Python依赖注入库
inseminator的Python项目详细描述
受精器
(定义自dictionary.com网站)
a technician who introduces prepared
semendependencies into thegenital tract of breeding animalspython classes, especiallycows and marespure classes with proper IoC, forartificial inseminationwell coupled components and clear classes signatures.
用于基于类型的依赖注入的Python库。编写没有全局状态的代码 还有嘈杂的样板。受精器是用来在你的入口点层 应用程序,它唯一需要的是正确的类型暗示类 依赖关系。在
安装
使用pip工具安装。在
pip install inseminator
使用
首先定义依赖项的container。只要你想要这个容器 要解析依赖项,它使用容器搜索现有对象和 解析器自动创建所需的依赖项。在
^{pr2}$解析Controller
的策略是其构造函数签名。解析器的工作原理如下。在
- 我们要求
container
解析依赖项Controller
->;container.resolve(Controller)
。在 container
中的解析器检查Controller
的构造函数签名,即类型提示 方法的__init__
,并看到{}。在 - 如果
DomainModel
类的一个实例已经被container
知道,那么它将使用该实例。 在相反的情况下,容器为DomainModel
启动相同的解析机制,它 就是我们现在面临的情况。在 - 因为
DomainModel
没有任何依赖项,所以它可以直接构造它。在 - 现在解析器拥有
Controller
构造函数的所有依赖项,并可以实例化它。在
如果我们针对接口而不是实现进行编程,那么示例将被修改为这样。在
frominseminatorimportContainerfromtypingimportProtocolclassDomainModel(Protocol):defdomain_logic(self,input_value:int)->int:...classController:def__init__(self,domain_model:DomainModel):self.__domain_model=domain_modeldefhandler(self,input_value:int)->int:returnself.__domain_model.domain_logic(input_value)# domain model implementationclassConcreteDomainModel:def__init__(self):self.__logic_constant=1defdomain_logic(self,input_value:int)->int:returninput_value+self.__logic_constant# entry point of your applicationcontainer=Container()container.register(DomainModel,value=ConcreateDomainModel())# view layer handlingcontroller=container.resolve(Controller)result=controller.handler(1)print(result)
在这种情况下,协议DomainModel
不包含实现细节,只保存接口。
使用
container.register(DomainModel, value=ConcreateDomainModel())
我们将指导解析器使用ConcreateDomainModel
的实例,以防有人提出请求
对于DomainModel
。在
强制参数
如果不希望为抽象或协议依赖提供单一的具体实现
可以强制解析器对指定参数使用具体类型。只需调用container.resolve
还有关键字,告诉解析它应该如何解析某些特定的参数。在
container=Container()controller=container.resolve(Controller,domain_model=ConcreteDomainModel())
此外,使用这种方法ConcreteDomainModel
不会被计算并保存在容器中,而是
而是在一个只存在于解析过程中的子容器中。因此,如果我们想创造
另一个依赖于DomainModel
的实例,我们必须使用register
或再次指定
解析过程中的参数。在
注入函数
在适当的地方指定函数的依赖项可能更方便。最好的例子是烧瓶
处理程序函数。它应该位于DI容器所在的同一层,因为它提供
只有基础设施的功能和它唯一想要做的事情,它调用域层的
功能。为此,在Container
对象上有injector
装饰器。你只是
告诉使用Depends
类型构造函数提供哪个依赖项。在
frominseminatorimportContainer,DependsclassDependency:def__init__(self):self.x=1container=Container()@container.injectdefmy_handler(input_value:int,dependency:Depends(Dependency)):returninput_value+dependency.x
像这样使用,my_handler
只接受一个参数,由于闭包,它有dependency
使用Dependency
的正确实例准备。在
>>> my_handler(1)
2
默认参数值
当指定了默认参数时,除非我们重写该值,否则解析器将使用它们 通过强制参数。在
defMyDependency:def__init__(self,parameter:int=1)->None:self.parameter=parametermy_dependency=container.resolve(MyDependency)assertmy_dependency.parameter==1
文件
- 项目
标签: