You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyNest(基于FastAPI)依赖注入每次请求重复初始化服务类问题求解

解决方案:利用PyNest的依赖注入单例模式

要解决每次请求重新初始化ProductService的问题,核心是让服务被DI容器以单例模式管理,确保应用启动时仅初始化一次。具体步骤如下:

1. 为服务添加@Injectable装饰器

PyNest的依赖注入容器需要通过@Injectable装饰器识别可管理的服务类,默认情况下该装饰器会将服务注册为单例。

2. 调整数据库会话的获取方式

单例服务中不应持有长期的数据库会话(会导致并发请求冲突),需将会话获取移至方法层面,通过Depends每次请求注入新会话。

修改后的服务代码

from src.product.product_model import Product
from src.product.product_entity import Product as ProductEntity
from orm_config import config
from nest.core.decorators import db_request_handler, Injectable
from nest.core import Depends
import time

@Injectable()  # 注册为单例服务
class ProductService:

    def __init__(self):
        self.orm_config = config
        # 耗时的初始化操作(如资源加载)仅在应用启动时执行一次
        time.sleep(5)
    
    @db_request_handler
    def get_products(self, session=Depends(config.get_db)):
        # 每次请求获取独立的数据库会话
        return session.query(ProductEntity).all()

控制器代码无需修改

原控制器的Depends(ProductService)会自动从DI容器获取单例实例,无需额外调整:

from nest.core import Controller, Get, Post, Depends, Put, Delete

from src.product.product_service import ProductService
from src.product.product_model import Product

@Controller("product")
class ProductController:

    service: ProductService = Depends(ProductService)
    
    @Get("/get_products")
    def get_products(self):
        return self.service.get_products()

原理说明

  • @Injectable()装饰器告诉PyNest的DI容器:这个类需要被容器管理,且默认创建单例实例(应用启动时初始化一次,后续所有请求复用)。
  • 将数据库会话通过Depends(config.get_db)注入到方法参数,确保每个请求都使用独立的会话,避免单例持有的会话引发并发问题。
  • 原代码中未使用@Injectable,导致每次调用Depends(ProductService)都会创建新的服务实例,从而重复执行__init__中的耗时操作。

内容的提问来源于stack exchange,提问作者ItayDar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:55:13