比如我现在有个token认证系统,目前我用mysql的token表实现,将来有可能会改成redis,怎么实现未来的无缝连接呢。

先定义一个合约文件app/Contracts/TokenHandler.php

  1. <?php
  2.  
  3. namespace App\Contracts;
  4.  
  5. /**
  6. * 处理Token的Contracts
  7. * @package App\Contracts
  8. */
  9. interface TokenHandler
  10. {
  11. /**
  12. * 创建一个token
  13. * @param $userId integer 用户Id
  14. * @return string
  15. */
  16. public function createToken($userId);
  17.  
  18. /**
  19. * 得到该token的用户
  20. * @param $token string token值
  21. * @return \App\User 拥有该token的用户
  22. */
  23. public function getTokenUser($token);
  24.  
  25. /**
  26. * 删除一个token
  27. * @param $token string token值
  28. * @return bool 是否成功
  29. */
  30. public function removeToken($token);
  31. }

  这里定义了3个方法:创建token,得到token对应用户,删除token。

然后我们写一个Mysql下的实现app/Services/MysqlTokenHandler.php

  1. <?php
  2.  
  3. namespace App\Services;
  4.  
  5. use App\Contracts\TokenHandler;
  6. use App\Orm\Token;
  7.  
  8. /**
  9. * 处理Token的Contracts对应的Mysql Service
  10. * @package App\Services
  11. */
  12. class MysqlTokenHandler implements TokenHandler
  13. {
  14. /**
  15. * @var int 一个用户能够拥有的token最大值
  16. */
  17. protected $userTokensMax = 10;
  18.  
  19. /**
  20. * @inheritdoc
  21. */
  22. public function createToken($userId)
  23. {
  24. while (Token::where('user_id', $userId)->count() >= $this->userTokensMax) {
  25. Token::where('user_id', $userId)->orderBy('updated_at', 'asc')->first()->delete();
  26. }
  27.  
  28. $token = \Illuminate\Support\Str::random(32);
  29. if (!Token::create(['token' => $token, 'user_id' => $userId])) {
  30. return false;
  31. }
  32.  
  33. return $token;
  34. }
  35.  
  36. /**
  37. * @inheritdoc
  38. */
  39. public function getTokenUser($token)
  40. {
  41. $tokenObject = Token::where('token', $token)->first();
  42.  
  43. return $tokenObject && $tokenObject->user ? $tokenObject->user : false;
  44. }
  45.  
  46. /**
  47. * @inheritdoc
  48. */
  49. public function removeToken($token)
  50. {
  51. return Token::find($token)->delete();
  52. }
  53. }

然后在bootstrap/app.php里绑定两者的映射关系:

  1. $app->singleton(
  2. App\Contracts\TokenHandler::class,
  3. App\Services\MysqlTokenHandler::class
  4. );

如果将来换成了redis,只要重新写一个RedisTokenHandler的实现并重新绑定即可,具体的业务逻辑代码不需要任何改变。

于是在controller里就可以直接注入该对象实例,只要在参数前声明合约类型:

  1. public function logout(Request $request, TokenHandler $tokenHandler)
  2. {
  3. if ($tokenHandler->removeToken($request->input('api_token'))) {
  4. return $this->success([]);
  5. } else {
  6. return $this->error(Lang::get('messages.logout_fail'));
  7. }
  8. }

  

也可以在代码里手动得到注入对象的实例,比如:

  1. $currentUser = app(\App\Contracts\TokenHandler::class)->getTokenUser($request->input('api_token'));

  

lumen的自定义依赖注入的更多相关文章

  1. angular中自定义依赖注入的方法和decorator修饰

    自定义依赖注入的方法 1.factory('name',function () { return function(){ } }); 2.provider('name',function(){ thi ...

  2. Asp.net core自定义依赖注入容器,替换自带容器

    依赖注入 在asp.net core程序中,众所周知,依赖注入基本上贯穿了整个项目,以通用的结构来讲解,控制器层(Controller层)依赖业务层(Service层),业务层依赖于仓储层(Repos ...

  3. ASP.NET Core 6框架揭秘实例演示[04]:自定义依赖注入框架

    ASP.NET Core框架建立在一个依赖注入框架之上,已注入的方式消费服务已经成为了ASP.NET Core基本的编程模式.为了使读者能够更好地理解原生的注入框架框架,我按照类似的设计创建了一个简易 ...

  4. ASP.NET Core 依赖注入(DI)简介

    ASP.NET Core是从根本上设计来支持和利用依赖注入. ASP.NET Core应用程序可以通过将其注入到Startup类中的方法中来利用内置的框架服务,并且应用程序服务也可以配置为注入. AS ...

  5. ASP.NET Core 1.0基础之依赖注入

      来源https://docs.asp.net/en/latest/fundamentals/dependency-injection.html ASP.NET Core 1.0在设计上原生就支持和 ...

  6. 【Spring】IoC容器 - 依赖注入

    前言 上一篇文章已经学习了[依赖查找]相关的知识,这里详细的介绍一下[依赖注入]. 依赖注入 - 分类 因为自己是基于小马哥的脉络来学习,并且很认可小马哥梳理的分类方式,下面按照小马哥思想为[依赖注入 ...

  7. [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...

  8. ASP.NET Core中使用自定义MVC过滤器属性的依赖注入

    除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...

  9. C#自定义应用程序上下文对象+IOC自己实现依赖注入

    以前的好多代码都丢失了,加上最近时间空一些,于是想起整理一下以前的个人半拉子项目,试试让它们重生.自从养成了架构师视觉 搭建框架之后,越来 越看不上以前搭的框架了.先撸个上下文对象加上实现依赖注入.由 ...

随机推荐

  1. 《Java编程思想》第一二章

    前段时间一直通过网络教程学习Java基础,把面向对象部分学完之后本来打算继续深入学习,但是感觉自己操之过急了,基础根本不够扎实,所以入手了一本<Java编程思想>,希望先把基础打好,再深入 ...

  2. 基于PlatinumKit库的DLNA服务端开发

    首先,需要特别感谢蓝斯老师的资料,我这里有很大一部分是参考蓝斯老师的,附上传送门:http://blog.csdn.net/lancees/article/details/9178385 一.DLNA ...

  3. Java之初识

    今天开始学习Java 1.什么是Java? Java是1995年由sun公司推出的一门极富创造力的面向对象编程语言,是由Java之父詹姆斯格斯林博士设计的. Java名字的由来:据说,java刚刚设计 ...

  4. js如何获取样式?

    在某个项目中,我们经常会需要来获取某个元素的样式,比如说获取一个div的color:这样,新的问出现了, var style = box.style.width;console.log(style); ...

  5. 8位基本定时器(TIM4)

    简介:该定时器由一个带可编程预分频器的8位自动重载的向上计数器所组成,它可以用来作为时基发生器,具有溢出中断功能. 主要功能: (1)8位向上计数的自动重载计数器: (2)3位可编程的预分配器(可在运 ...

  6. java 对象与json互转

    有时为了项目需求,会将对象数据转换成json数据,以下是个人根据项目需求实现的方法. 项目中需要将数据格式: [{ "node": "0", "ind ...

  7. Spark的误解-不仅spark是内存计算,hadoop也是内存计算

    市面上有一些初学者的误解,他们拿spark和hadoop比较时就会说,Spark是内存计算,内存计算是spark的特性.请问在计算机领域,mysql,redis,ssh框架等等他们不是内存计算吗?依据 ...

  8. 用js写一个回车键盘事件

    用js来监听键盘事件,代码如下: <script type="text/javascript" language=JavaScript charset="UTF-8 ...

  9. js数组拍平

    js数组拍平 var arr=[1,[[[7,2],8,9],3]]; function f(arr) { if (Object.prototype.toString.call(arr) != &qu ...

  10. centos下-MariaDB的安装

    安装命令: yum install mariadb mariadb-server 服务命令: systemctl start|stop|restart mariadb root用户密码设置 mysql ...