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

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

<?php

namespace App\Contracts;

/**
* 处理Token的Contracts
* @package App\Contracts
*/
interface TokenHandler
{
/**
* 创建一个token
* @param $userId integer 用户Id
* @return string
*/
public function createToken($userId); /**
* 得到该token的用户
* @param $token string token值
* @return \App\User 拥有该token的用户
*/
public function getTokenUser($token); /**
* 删除一个token
* @param $token string token值
* @return bool 是否成功
*/
public function removeToken($token);
}

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

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

<?php

namespace App\Services;

use App\Contracts\TokenHandler;
use App\Orm\Token; /**
* 处理Token的Contracts对应的Mysql Service
* @package App\Services
*/
class MysqlTokenHandler implements TokenHandler
{
/**
* @var int 一个用户能够拥有的token最大值
*/
protected $userTokensMax = 10; /**
* @inheritdoc
*/
public function createToken($userId)
{
while (Token::where('user_id', $userId)->count() >= $this->userTokensMax) {
Token::where('user_id', $userId)->orderBy('updated_at', 'asc')->first()->delete();
} $token = \Illuminate\Support\Str::random(32);
if (!Token::create(['token' => $token, 'user_id' => $userId])) {
return false;
} return $token;
} /**
* @inheritdoc
*/
public function getTokenUser($token)
{
$tokenObject = Token::where('token', $token)->first(); return $tokenObject && $tokenObject->user ? $tokenObject->user : false;
} /**
* @inheritdoc
*/
public function removeToken($token)
{
return Token::find($token)->delete();
}
}

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

$app->singleton(
App\Contracts\TokenHandler::class,
App\Services\MysqlTokenHandler::class
);

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

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

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

  

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

                $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. 工厂设计模式 Factory

    Factory 主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类. 例如:汽车销售商场 该模式将创建对象的过程放在了一个静态方法中来实现.在实际编程中,如果需要大量的创建对象,该模 ...

  2. 如何安装Orchard

    本篇文章主要讲解如何安装Orchard,首先说一下Orchard的安装方式有如下几种: 通过Microsoft WebMatrix(Microsoft Web Platform Installer)安 ...

  3. 20170717_python_爬虫_网页数据解析_BeautifulSoup_数据保存_pymysql

    上午废了老大劲成功登陆后,下午看了下BeautifulSoup和pymysql,晚上记录一下 自己电脑装的sublime,字体颜色竟然拷贝不下来 - - 写的过程中遇到了很多问题: 1.模拟登陆部分 ...

  4. 微信小程序怎么用?线下商家最适合玩小程序

    随着微信小程序不断地释放新功能,许多行业越来越关注小程序,目前已经有不少餐饮和线下传统零售企业开始谋划利用好小程序.但是,线下商业有着复杂的场景,如何针对自己行业的特点和需求开发出属于自己的小程序,是 ...

  5. PXE+Kickstart无人值守安装操作系统

    1.PXE的工作过程: 1. PXE Client 从自己的PXE网卡启动,向本网络中的DHCP服务器索取IP: 2. DHCP 服务器返回分配给客户机的IP 以及PXE文件的放置位置(该文件一般是放 ...

  6. 基于Spring4的定时任务管理

    在项目中,有时会遇到定时任务的处理,下面介绍一下我的做法. 此做法基于Spring4,Spring框架搭建成功,另需引入quartz.jar,pom.xml文件中加入 <dependency&g ...

  7. Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners 约定web.xml配置的contextClass为默认值XmlWebAppl ...

  8. DDD理论学习系列(12)-- 仓储

    DDD理论学习系列--案例及目录 1. 引言 DDD中Repository这个单词,主要有两种翻译:资源库和仓储,本文取仓储之译. 说到仓储,我们肯定就想到了仓库,仓库一般用来存放货物,而仓库一般由仓 ...

  9. 学生成绩管理系统——C语言实现

    一.功能实现: 0.浏览学生信息 1.输入学生信息 2.增加学生信息 3.修改学生信息 4.删除学生信息 5.按学号查询 6.按班级查询 7.按姓名查询 8.按课堂名称查询 9.按总分高低排序 10. ...

  10. 蓝桥杯比赛javaB组练习《饮料换购》

    题目如下: 饮料换购 乐羊羊饮料厂正在举办一次促销优惠活动.乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去,但不允许赊账. 请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么 ...