哈Ha!我已经发布了依赖注入器的新的主要版本。
此版本的主要功能是接线。它允许您注入函数和方法,而无需将其拖动到容器中。
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
)
service = providers.Factory(
Service,
api_client=api_client,
)
def main(service: Service = Provide[Container.service]):
...
if __name__ == '__main__':
container = Container()
container.config.api_key.from_env('API_KEY')
container.config.timeout.from_env('TIMEOUT')
container.wire(modules=[sys.modules[__name__]])
main() # <--
with container.api_client.override(mock.Mock()):
main() # <--
调用该函数时,将自动收集并传递
main()
依赖项Service
。
在测试过程中,它被调用
container.api_client.override()
以用模拟代替API客户端。调用时,main()
依赖项Service
将收集模拟。
这项新功能使Dependency Injector与其他Python框架一起使用变得更加容易。
链接如何与其他框架集成?
不论应用程序的结构如何,绑定都能实现精确的注入。与版本3不同,依赖项注入不需要将函数或类拉入容器。
Flask示例:
import sys
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide
from flask import Flask, json
class Service:
...
class Container(containers.DeclarativeContainer):
service = providers.Factory(Service)
def index_view(service: Service = Provide[Container.service]) -> str:
return json.dumps({'service_id': id(service)})
if __name__ == '__main__':
container = Container()
container.wire(modules=[sys.modules[__name__]])
app = Flask(__name__)
app.add_url_rule('/', 'index', index_view)
app.run()
其他例子:
绑定如何工作?
为了应用绑定,您需要:
- 将标记放置在代码中。视图标记被
Provide[Container.bar]
指定为函数或方法参数的默认值。需要标记来指示嵌入的内容和位置。 - 将容器与代码中的标记相关联。为此,您需要调用container.wire(modules = [...],packages = [...])方法,并指定具有标记的模块或软件包。
- 照常使用函数和方法。该框架将自动准备并注入所需的依赖项。
绑定基于自省。调用时,
container.wire(modules=[...], packages=[...])
框架将遍历这些包和模块中的所有功能和方法,并检查其默认参数。如果默认参数是标记,那么依赖注入装饰器将修补此类函数或方法。调用此装饰器时,它会将依赖项(而不是标记)准备并注入到原始函数中。
def foo(bar: Bar = Provide[Container.bar]):
...
container = Container()
container.wire(modules=[sys.modules[__name__]])
foo() # <--- "bar"
# :
foo(bar=container.bar())
在此处 了解有关链接的更多信息。
兼容性?
版本4.0与版本3.x兼容。
集成模块
ext.flask
并ext.aiohttp
倾向于捆绑。
使用时,框架将显示警告并建议切换到链接。
完整的更改列表可在此处找到。