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
相关产品推荐
相关产品推荐

