基于类型提示的Python依赖注入库

inseminator的Python项目详细描述


受精器

codecovCode style: black

(定义自dictionary.com网站)

a technician who introduces prepared semendependencies into the genital tract of breeding animals python classes, especially cows and mares pure classes with proper IoC, for artificial insemination well coupled components and clear classes signatures.

用于基于类型的依赖注入的Python库。编写没有全局状态的代码 还有嘈杂的样板。受精器是用来在你的入口点层 应用程序,它唯一需要的是正确的类型暗示类 依赖关系。在

安装

使用pip工具安装。在

pip install inseminator

使用

首先定义依赖项的container。只要你想要这个容器 要解析依赖项,它使用容器搜索现有对象和 解析器自动创建所需的依赖项。在

^{pr2}$

解析Controller的策略是其构造函数签名。解析器的工作原理如下。在

  1. 我们要求container解析依赖项Controller->;container.resolve(Controller)。在
  2. container中的解析器检查Controller的构造函数签名,即类型提示 方法的__init__,并看到{}。在
  3. 如果DomainModel类的一个实例已经被container知道,那么它将使用该实例。 在相反的情况下,容器为DomainModel启动相同的解析机制,它 就是我们现在面临的情况。在
  4. 因为DomainModel没有任何依赖项,所以它可以直接构造它。在
  5. 现在解析器拥有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

文件

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
virtualbox无法从java移动共享文件夹中的文件   java如何连接Android 4.3.5(GA)的apache HttpClient库?   片段中的java Recyclerview未立即显示警报对话框结果   javac(n,r)计算器程序不工作   java使用BooleanQuery还是编写更多索引?   如何在java中设置y/n循环?   java不兼容的通用通配符捕获   java如何在安卓xml中编写数据绑定时的三元操作条件   java如何使用FileDialog?   java如何创建单元测试来检测是否有人使用错误的编码编辑了文件?   java如何从唯一的字符串生成唯一的int?   java gradletomcatplugin:log4j:WARN找不到记录器的附加程序   java我的动态编程解决方案(Kefa和第一步)在codeforces中有什么问题?   java每天更新两个数据库,使它们都包含相同的有效数据集   java如何检查给定的时间是否在时间限制之间   java在单个json POST上保存父级和子级   java如何获取Solr字段类型