(Laravel) 基于用户输入的接口动态依赖注入

2023-12-21

我目前在架构和实现方面面临着一个非常有趣的困境。

我有一个名为ServiceInterface其中有一个方法称为execute()

然后我对该接口有两种不同的实现:Service1 and Service2,它正确地实现了execute方法。

我有一个名为MainController这个控制器有一个“类型提示”ServiceInterface (依赖注入),这意味着两者,Service1 and Service2,可以称为该依赖项注入的解析。

现在有趣的部分:

我不知道要使用哪些实现(Service1 or Service2)因为我只知道我是否可以使用其中之一基于用户输入从上一步开始。

这意味着用户选择一项服务,并根据该值我知道是否可以使用Service1 or Service2.

我目前正在使用会话值解决依赖注入,因此根据我返回实例或其他值的值,但我真的认为这不是一个好方法。

如果您遇到类似的问题,请告诉我,您如何解决它,或者我该怎么做才能以正确的方式实现这一目标。

提前致谢。如果需要更多信息,请告诉我。


最后,经过几天的研究和思考,我终于使用 Laravel 解决了这个问题的最佳方法。

我不得不说,这尤其困难Laravel 5.2因为,在这个版本中,Session中间件仅在路由中使用的控制器中执行,这意味着如果由于某种原因我使用控制器(未死记硬背链接)并尝试访问会话,这是不可能的。

因此,因为我无法使用会话,所以我决定使用 URL 参数。这里有解决方法;我希望你们中的一些人觉得它有用。

所以,你有一个界面:

interface Service
{
    public function execute();
}

然后是该接口的几个实现:

服务一:

class ServiceOne implements Service
{
    public function execute()
    {
        .......
    }
}

服务二.

class ServiceTwo implements Service
{
    public function execute()
    {
        .......
    }
}

有趣的是,我有一个控制器,其功能依赖于服务接口。尽管如此,我仍然需要根据用户输入将其动态解析为 ServiceOne 或 ServiceTwo。所以:

控制器

class MyController extends Controller
{
    public function index(Service $service, ServiceRequest $request)
    {
        $service->execute();
        .......
    }
}

请注意,ServiceRequest 验证了该请求已经具有我们需要解析依赖项的参数(将其称为'service_name')

现在,在 AppServiceProvider 中我们可以通过以下方式解决依赖关系:

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        
    }

    public function register()
    {
        //This specific dependency is going to be resolved only if
        //the request has the service_name field stablished
        if(Request::has('service_name'))
        {
            //Obtaining the name of the service to be used (class name)
            $className = $this->resolveClassName(Request::get('service_name')));
            
            $this->app->bind('Including\The\Namespace\For\Service', $className);
        }
    }

    protected function resolveClassName($className)
    {
        $resolver = new Resolver($className);
        $className = $resolver->resolveDependencyName();
        return $className;
    }
}

所以现在所有的责任都由 Resolver 类承担。该类基本上使用传递给构造函数的参数来返回将用作 Service 接口的实现的类的全名(带有命名空间):

class Resolver
{
    protected $name;
    public function __construct($className)
    {
        $this->name = $className;
    }

    public function resolveDependencyName()
    {
        //This is just an example, you can use whatever as 'service_one'
        if($this->name === 'service_one')
        {
            return Full\Namespace\For\Class\Implementation\ServiceOne::class;
        }
        
        if($this->name === 'service_two')
        {
            return Full\Namespace\For\Class\Implementation\ServiceTwo::class;
        }
        //If none, so throw an exception because the dependency can not be resolved 
        throw new ResolverException;
    }
}

嗯,我真的希望它能对你们中的一些人有所帮助。

最好的祝愿!

- - - - - 编辑 - - - - - -

我只是意识到直接在 Laravel 容器内使用请求数据并不是一个好主意。从长远来看,这确实会造成一些麻烦。

最好的方法是直接注册所有可能支持的实例(serviceone 和 servicetwo),然后直接从控制器或中间件解析其中一个,因此控制器“决定”使用什么服务(从所有可用的服务中)基于请求的输入。

最后,它的工作原理是一样的,但它会让你工作得更自然。

我要感谢 Laravel 的 Slack Chat 问题频道的用户 rizqi。

他亲自打造了金article http://rizqi.id/laravel-registry-pattern对这个。请阅读它,因为它以非常正确的方式彻底解决了这个问题。

Laravel 注册表模式 http://rizqi.id/laravel-registry-pattern

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(Laravel) 基于用户输入的接口动态依赖注入 的相关文章

  • facebook php - 如何获取专辑封面照片

    我需要使用 PHP SDK Facebook 获取专辑封面照片 我尝试 https graph facebook com ALBUM ID picture type album 但我得到默认图像 例如 获取用户 https graph fa
  • PHP - 获取base64图像字符串解码并保存为jpg(生成空图像)

    嗨 我实际上是通过 ajax 发送一个 base64 图像字符串到一个 php 脚本 该脚本只是解码字符串并将内容保存为 jpg 文件 但结果是一张空图像 这怎么可能 PHP脚本 uploadedPhotos array photo 1 p
  • 从 octobercms 中的非 ajax 表单获取输入值

    我正在尝试构建一个简单的搜索功能 下面是我的搜索表格
  • 在字符串中间添加一个字符

    可能有一个简单的解决方案可以解决这个问题 但会引起面部表情 我将时间存储为 4 个字符长的字符串 即 1300 我试图将该字符串显示为 13 00 我觉得必须有一个比我现在正在做的更优雅的解决方案 我目前有 startTime get fi
  • 如何通过php的require()或include()函数传递变量?

    当我使用这个时 require diggstyle code php page page no 警告是 无法打开流 第 198 行 C xampp htdocs 4ajax gallery core php 中没有错误 错误是 Failed
  • PHP:读取字体文件的 TrueType/OpenType 元数据

    如何阅读字体详细信息 例如 字体在其元数据中包含版权 姓氏 设计者 版本等信息 我还希望脚本能够计算文件中的字形数量 并返回字体支持的语言 例如 典型的字体可能包含西方语言 瑞典语和罗马语言支持 并具有数百个字形 它应该支持 truetyp
  • 如何解码 eval( gzinflate( base64_decode(

    我已将此代码注入到我的网站中 如何解码尾随字符串 我需要知道发生了什么以及其背后的代码是什么 这应该输出将被执行的代码eval 我希望这就是您正在寻找的
  • Magento - 检查 cms 页面

    我想通过 php 检查页面是否是 Magento 中的 cms page 我需要不同的 cms 页面面包屑 所以我尝试在一个条件下做到这一点 但我不知道如何或在哪里查看 到目前为止 这是我的 breadcrumbs phtml p some
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • apache_request_headers() 与 $_SERVER

    据我所知 apache request headers 提供与以下相同的信息 SERVER 但按键略有不同 为什么有人应该使用apache request headers 而不仅仅是从那里获取这些信息 SERVER 我在 Centos 上使
  • postgreSql 中特定时间后表更新

    我已经在 postgres 中创建了表 现在我想在特定时间 例如 1 小时 后更新一行 我看到很多问题 例如 https dba stackexchange com questions 56424 column auto updated a
  • JavaScript 验证和 PHP 验证?

    我正在使用 jquery 验证插件来验证空表单 我还应该在 PHP 中检查一下以确保 100 正确吗 或者用 javascript 验证就可以了 谢谢 您应该始终在服务器上进行验证 如果用户以某种方式不使用 Javascript 提交表单
  • 这个条带请求是什么?为什么它会多次触发?

    对于使用 stripe 的 Laravel 应用程序 此请求https r stripe com 0被解雇多次 如下所示 我刷新主页后 这些请求立即被触发 问题是我最近得到了一个429 too many requests我的实时服务器出现错
  • URL 中的 %2F 中断并且未引用所需的 .php 文件 [重复]

    这个问题在这里已经有答案了 我需要将 作为变量作为 URL 的一部分传递 我的结构如下所示 www domain com listings page 1 city Burnaby South type Townhome bedroom 2
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 如何使用 PHP 对字符串进行 rot13 处理?

    我有一个很大的 php 代码 我想手动对其进行编码和解码 我的问题是 php 代码里面有很多单引号和双引号 因此我在使用时出现错误str rot13 功能如下 那么正确的语法是什么以及如何使用下面的函数进行编码 str rot13 That
  • 检查 $_POST 数据

    我正在对表单进行一些垃圾邮件检查 下面的代码在我的本地主机上正常工作 如果为 true 则重定向到 google com 但是 当它在生产服务器上时却不起作用 执行脚本的其余部分并且不重定向到 Google com if POST SERV
  • php curl 使用 GET 发送变量 奇怪的结果

    我正在尝试调用远程站点上页面中的网址 决定使用curl 在远程站点上 url 变量显示为 REQUEST Array var1 gt val1 amp var2 gt val2 amp var3 gt val3 被调用的url是 http
  • 如何在laravel中注册后自动登录

    我在 laravel 中注册用户时遇到问题 user假设是包含所有数组元素的数组 同时自动登录以下代码结果false 数据库中保存的密码是hash make password user id this gt user model gt ad
  • 为什么我的会话仍然存在?

    我一定很愚蠢 因为似乎一件相当明显的事情现在让我完全困惑 我有一个会议 ie SESSION handbag id 在某个时刻 我需要彻底终止这个会话 ie at the start of the page session start el

随机推荐

  • 通过提供 sys 路径来使用包

    我发现了这个链接 Python 在本地使用库而不是安装它 https stackoverflow com questions 9059699 python use a library locally instead of installin
  • const_cast VS 可变?有什么区别吗?

    据我了解 mutable取消constness一个变量的 Class A void foo const m a 5 mutable int m a 但是也const cast void print char str cout lt lt s
  • .Net Framework 4.0 安装程序是否包含 .Net Framework 3.5?

    针对 Net Framework 3 5 编译的 Net 组件是否可以在仅安装 Net Framework 4 0 的系统上运行 或者换句话说 Net Framework 4 0 安装程序是否包含 Net Framework 3 5 NET
  • 如何让游戏忽略Unity3D中UI按钮的点击?

    我有一个用户界面Button using UnityEngine UI 然而 点击Button似乎是点击浏览到场景中 在我的例子中单击导航网格 如何解决这个问题呢 我一直在使用典型的 Unity3D 代码来让用户投入游戏 例如 if Inp
  • 将神经网络应用于可变长度语音片段的 MFCC

    我目前正在尝试创建和训练一个神经网络 以使用 MFCC 执行简单的语音分类 目前 我为每个样本使用 26 个系数 总共 5 个不同的类别 这些是具有不同音节数的五个不同单词 虽然每个样本都有 2 秒长 但我不确定如何处理用户可以非常慢或非常
  • Android 自定义 SQLite 构建 - 无法打开数据库

    我的目标是构建一个自定义版本的 SQLite 特别是启用了 R Tree 以包含在我的 Android 项目中 动机源于 Android SQLite R Tree 如何安装模块 https stackoverflow com questi
  • 使用 uwp 应用程序打开任何类型的文件(无需文件关联)

    我正在制作一个简单的 uwp 文本编辑器应用程序 我希望应用程序打开任何类型的文件 即使没有声明文件关联 因为有许多文本文件在操作系统中没有已知的扩展名 有什么方法可以修改注册表 让我的应用程序在 打开方式 列表中可用 例如记事本 以便用户
  • Python 中的快速字符串到整数转换

    实际上 这是一个简单的问题 您有 10 亿 1e 9 个无符号 32 位整数作为十进制 ASCII 字符串存储在 TSV 制表符分隔值 文件中 转换使用int 与处理相同数据集的其他工具相比 速度非常慢 为什么 更重要的是 如何让它更快 因
  • 使用 WIX 并行安装同一 IIS 站点的版本

    是否可以使用 WIX 并行安装同一 IIS 网站的多个版本 包括单独升级它们的能力吗 我到处搜索 但在互联网上找不到任何相关内容 另外 为什么在每次构建时使用热量自动收集文件是不可以的 如果您在开发过程中大量添加视图 模型 控制器 那么当文
  • Java系统命令从文件加载sqlite3 db失败

    我正在尝试使用 java 运行系统命令来从 sql 文件加载 sqlite3 数据库 sql 文件中没有错误 它可以使用命令行中的常规方法加载正常 sqlite3 dbname lt file sql 我的方法 public void lo
  • 如何使用 Angular cli 在 Angular 2 中导入 Electron

    我正在尝试使用 Angular 2 配置了最新的基于 webpack 的 Angular cli 为 gui 构建 Electron 应用程序原型 但我陷入困境 因为我不知道如何在 Angular2 组件中导入 Electron api 具
  • 在 ember 中记录单选按钮的值

    我对 Ember 相当陌生 使用版本 0 2 3 我有一个带有一些计算值的组件 他们从输入字段收集这些计算值 export default Component extend loanAmount 200000 deductible 0 de
  • ExtJS - 动态格式化 GridPanel 行?

    我有带有布尔值的记录 并且根据布尔值 我希望 GridPanel 的行呈现为粗体 我确信有一个很好的 GridView 风格的方法可以做到这一点 但我似乎找不到它 Thanks 您的答案是正确的 但我想指出 无需提供实例化的 GridVie
  • 将用户输入从 NodeJS 发送到 shell 脚本

    我有这个 NodeJS 脚本 var util require util process require child process ls process exec test sh ls stdout on data function da
  • Mapbox GL JS:如果单击标记,则忽略地图单击事件

    我在地图上有一个标记 我想在单击它时更改其状态 并在单击地图上的其他位置时将其更改回来 问题是map on click console log 单击标记时也会触发 我只想查看标记单击事件 因为地图单击会调用状态回滚
  • 使用 Jersey 上传文件:FormDataContentDisposition 为 null

    我正在尝试使用 Jersey 实现文件上传 所以我遵循了这个示例 http www mkyong com webservices jax rs file upload example in jersey http www mkyong co
  • Moment js 将毫秒转换为日期和时间

    我的当前时间以毫秒为单位 1454521239279 如何将其转换为 03 FEB 2016 和时间 11 10 PM 矩解析器 moment 1454521239279 format DD MMM YYYY hh mm a parse i
  • 致命:无法获取凭证存储锁:文件存在

    我正在使用 git scm 并尝试推送到存储库 这样做后 我收到了以下消息 fatal unable to get credential storage lock File exists 虽然推送最终确实推送成功 但我想知道为什么会出现这个
  • 如何将 FlowDocument 中的表格放在一起?

    我想如果我将表格放在段落中 我可以使用 KeepTogether 属性将表格保持在一起 该表格用于报告的总计 客户不希望它们分成两页 想象一下 表中有 5 行 我快要疯了 不知道下一步该尝试什么 最后一行代码 myFlowDocument
  • (Laravel) 基于用户输入的接口动态依赖注入

    我目前在架构和实现方面面临着一个非常有趣的困境 我有一个名为ServiceInterface其中有一个方法称为execute 然后我对该接口有两种不同的实现 Service1 and Service2 它正确地实现了execute方法 我有