likes
comments
collection
share

FastApi(自用脚手架)+Snowy搭建后台管理系统(11)- 使用装饰器方式注入类形式依赖项

作者站长头像
站长
· 阅读数 17

前言

之前在定义我们的逻辑处理的时候,我个人是通过定义类的方式来处理,如下的代码所示:

@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

会直接的爆出错误信息如下所示:

FastApi(自用脚手架)+Snowy搭建后台管理系统(11)- 使用装饰器方式注入类形式依赖项 所以我们需要做相关的判断处理,但是你仔细想想如果一个类没有任何参数的话,好像也没有必要定义成为这种依赖项的形式了,所以暂时不考虑如上类的定义方式,如果非要实现的话,其实没有意义,因为一个依赖项一般都需要对应处理返回结果,但是上面那方式没有返回结果,所以感觉没必要!如果非必要的,只能判断被装饰器的类是不是一个可调用的对象,修改装饰为如下的形式:

def RestControllerWithDepends():
    def back(cls):
        return Depends(cls)
    return back

不过感觉没必要!这个看个人需求了! 至此,关于【实现 使用装饰器方式注入类形式依赖项】相关介绍分享已完成!以上内容分享纯属个人经验,仅供参考!

文笔有限,如有笔误或错误!欢迎批评指正!感谢各位大佬!有什么问题也可以随时交流!

结尾

END

简书:www.jianshu.com/u/d6960089b…

掘金:juejin.cn/user/296393…

公众号:微信搜【程序员小钟同学】

新开QQ群号,欢迎随时加群交流,相互学习。QQ群号:247491107

小钟同学 | 文 【欢迎一起学习交流】| QQ:308711822