FastApi(自用脚手架)+Snowy搭建后台管理系统(11)- 使用装饰器方式注入类形式依赖项
前言
之前在定义我们的逻辑处理的时候,我个人是通过定义类的方式来处理,如下的代码所示:
@get(path='/b/getPicCaptchanew/', summary="你好")
async def getPicCaptcha(self, controller: IBaseController = Depends(GetPicCaptchaController)):
'''
ASDHJASHJDAH
:return:
'''
return await controller.async_response()
@post("/b/doLogin2/", name='AAAAAAAAAAAAAAAAAAAA', summary='执行登入接口')
async def doLogin(self, controller: IBaseController = Depends(DoLoginController)):
'''
输入账号登入
:param request:
:return:
'''
return await controller.async_response()
在上面的代码中,我们是通过 Depends(DoLoginController)的方式实现我们定义的类实现的,其中DoLoginController的代码如下所示:
from fastapi import Request, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from afast_core.core_plugins.db.sqlalchemy import async_session_class_v2_dependency
from afast_core.core_tools.jwt_helper import SimpleAuth
from snowy_src.snowy_common.snowy_controller.decorater import wrapper_record_background_task
from snowy_src.snowy_common.snowy_errors.enums import SnowySystemResultEnum
from snowy_src.snowy_common.snowy_errors.exception import SnowyBusinessException
from snowy_src.snowy_system.snowy_modules.auth.controllers.base import IAuthIBaseController
from snowy_src.snowy_system.snowy_modules.auth.enums import SaClientTypeEnum
from snowy_src.snowy_system.snowy_modules.auth.repository.user import SysUserCRUDRepository
from snowy_src.snowy_system.snowy_modules.auth.schemas import AuthAccountPasswordLoginParam
class IDoLoginControllerBaseController(IAuthIBaseController):
'''
定制相关约束检测函数逻辑步序
'''
pass
class IDoLoginController(IDoLoginControllerBaseController):
'''
定制相关约束检测函数逻辑步序
'''
def __init__(self, *, request: Request,
async_session: AsyncSession = Depends(async_session_class_v2_dependency),
schema_param: AuthAccountPasswordLoginParam,
):
super().__init__(request=request, async_session=async_session)
# 入参参数
self.schema_param = schema_param
self.sysuser_repo = SysUserCRUDRepository(self.async_session)
self.userinfo = None
class DoLoginController(IDoLoginController):
# @wrapper_record_background_task
async def business_login(self):
# 把相关业务逻辑分到authService服务中处理
# return await self.authService.doLogin(self.schema_param, SaClientTypeEnum.B.value)
return await self.doLogin()
async def doLogin(self):
'''
账号密码登录
:param schema: 账号密码登入模型对象
:param type: 指定用户登入的类型
:return:
在上面的代码中,其实我们的对于在路由中使用如下代码所示:
@post("/b/doLogin2/", name='AAAAAAAAAAAAAAAAAAAA', summary='执行登入接口')
async def doLogin(self, controller: IBaseController = Depends(DoLoginController)):
感觉起来不是非常优雅,所以接下来的打算还是,想着能不能使用装饰器的注入类,然后注解的加到路由上即可,如下所示:
@post("/b/doLogin2/", name='AAAAAAAAAAAAAAAAAAAA', summary='执行登入接口')
async def doLogin(self, controller: DoLoginController):
'''
输入账号登入
:param request:
:return:
'''
return await controller.async_response()
实现思路
首先我们需要明确一点依赖项必须是一个可调用的对象,所以我们需要注意这点,所以我们的可以首先定义装饰器,如下代码所示:
def RestControllerWithDepends(*args, **kwargs):
def back(cls):
return Depends(cls(*args, **kwargs))
return back
该装饰器接收相关类可以传入的参数信息。然后定义具体被上面装饰器的依赖项类,如下:
@RestControllerWithDepends()
class DoLoginController:
def __init__(self):
pass
def __call__(self):
return "你好,我是没有参数被当做依赖项的类"
@RestControllerWithDepends(content='你是说我是谁呢?')
class DoLoginController2:
def __init__(self, content: str):
self._content = content
def __call__(self):
return "你好,我是一个有参数被当做依赖项的类" + self._content
到此为止,我们的就完整相关使用装饰器装饰某一个类为一个依赖处理。最后我们的把该类直接的写入路由上,如下代码所示:
@app.get('/1')
def login1(test: str = DoLoginController):
return "test:001" + test
@app.get('/2')
def login2(test: str = DoLoginController2):
return "test:002" + test
然后我们就可以实现类似 使用装饰器方式注入类形式依赖项的功能了。但是上面有一种情况就是假如我的类不是一个可调用对象,也就是说我类没有 call(self):函数,那么我的装饰器那种写法就有问题,比如下面的写法:
def RestControllerWithDepends(*args, **kwargs):
def back(cls):
return Depends(cls(*args, **kwargs))
return back
@RestControllerWithDepends()
class DoLoginController:
pass
会直接的爆出错误信息如下所示:
所以我们需要做相关的判断处理,但是你仔细想想如果一个类没有任何参数的话,好像也没有必要定义成为这种依赖项的形式了,所以暂时不考虑如上类的定义方式,如果非要实现的话,其实没有意义,因为一个依赖项一般都需要对应处理返回结果,但是上面那方式没有返回结果,所以感觉没必要!如果非必要的,只能判断被装饰器的类是不是一个可调用的对象,修改装饰为如下的形式:
def RestControllerWithDepends():
def back(cls):
return Depends(cls)
return back
不过感觉没必要!这个看个人需求了! 至此,关于【实现 使用装饰器方式注入类形式依赖项】相关介绍分享已完成!以上内容分享纯属个人经验,仅供参考!
文笔有限,如有笔误或错误!欢迎批评指正!感谢各位大佬!有什么问题也可以随时交流!
结尾
END
简书:www.jianshu.com/u/d6960089b…
公众号:微信搜【程序员小钟同学】
新开QQ群号,欢迎随时加群交流,相互学习。QQ群号:247491107
小钟同学 | 文 【欢迎一起学习交流】| QQ:308711822