工厂中的依赖注入

2024-04-23

我对 DI 很陌生,但我真的很想尝试使用它。

有件事我不明白。这是一个简单的工厂伪代码,我经常使用。

class PageFactory {
   public function __construct(/* dependency list */) {
      ... //save reference to the dependencies
   }

   public function createPage($pagename) {
       switch ($pagename) {
           case HomePage::name:
               return new HomePage(/* dependency list */);
           case ContactPage::name:
               return new ContactPage(/* dependency list */);
           ...
           default:
               return null;
       }
   }
}

它有一个非常简单的逻辑,它根据字符串选择实现实例。它非常有用,因为我可以稍后选择我需要的页面,并且只会创建该页面。

我将如何重写此代码,以便我的页面实例将由依赖项容器创建,这样我就不需要处理工厂及其创建的页面的依赖项?

我看到的唯一解决方案是使我想要使用的容器成为工厂的依赖项,并从工厂内部调用它。我对此有很多问题。

首先,我不想将容器耦合到我的应用程序及其拥有的每个工厂中。

其次,我最大的问题是,对容器的调用确实很混乱,它是字符串类型的(即$容器->获取('Foo');)。我想尽可能少地使用它。如果可能的话,只进行一次。

EDIT:

我不想写一个 DI 容器。我想使用现有的。我的问题是关于使用情况。我将如何使用 DI 容器来代替或在上述工厂中使用,同时保留实例选择的逻辑。

EDIT 2:

我开始使用Dice https://r.je/dice.html作为 DI 容器,因为它是轻量级的,并且知道我需要的一切。我更希望能够在一个地方使用它并构建整个应用程序。为此,我需要一种方法来以某种方式摆脱这些工厂,或者以某种方式修改它,使这些页面表现得像依赖项,这样 DI 容器就会向它们提供实例。

EDIT 3:

是的,我需要这个用于测试目的。我也是测试新手,但到目前为止它非常棒,我真的很喜欢它。

这些页面就是 MVC 框架所称的控制器。但我检查的所有 MVC 框架都没有使其控制器可测试,因为它们会自动创建控制器的实例。并且因为它们是由系统创建的,所以它们的构造函数参数不能由用户自定义。

对于任何框架都有一个简单的方法来检查这一点。我只是查找在特定框架中的控制器中应该使用数据库的方式。大多数框架要么是程序性的,要么使用某种服务定位器,无论哪种方式,它们都会从公共范围获取依赖项,这是我不想做的事情。这就是为什么我没有自动化控制器实例化。缺点是我现在有这些奇怪的工厂,它们带有很多依赖项。我想将此任务替换为 DI 容器。

大多数框架都实现了自己的测试机制,这更像是功能测试,而不是单元测试,但我也不想这样做。


Note:依赖注入是一种设计模式,而 DI 容器是库,它们通过利用依赖注入来生成实例……或者它们是糟糕的服务定位器,有人是selling作为最新的热门话题

正确实施的 DI 容器基本上是一个“智能工厂”。但实施一项可能会远远超出您当前的能力。这真的有点复杂,因为一个好的 DI 容器will构建整个依赖关系树。

例如:

假设你有课Foo需要实例Alpha and Beta在构造中传递。但有一个问题。实例Beta构造函数中还需要一个 PDO DSN 和一个实例Cache.

A well made DI container will be able to construct the whole dependency tree at once.

您应该使用现有的 DI 容器,而不是自己制作一个。

我的建议是Auryn https://github.com/rdlowrey/Auryn.

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

工厂中的依赖注入 的相关文章

  • 用于查找 标记之间的所有内容的正则表达式

    我正在尝试找到一种方法来列出之间的所有内容 a and a 标签 所以我有一个链接列表 我想获取链接的名称 不是链接的位置 而是它们在页面上的名称 对我来说真的很有帮助 目前我有这个 lines preg split r n r conte
  • 当与不需要虚拟机的编译程序一起使用时,CGI 是否仍然很慢?

    当我学习 CGI 时 我了解到任何编程语言都可以用来将其输出挂钩到 http 响应消息 而它的输入是 http 请求消息 我读过的很多文章都在 Perl 的背景下讨论 CGI 这是因为 Perl 是与 CGI 结合使用的最常见的语言吗 我想
  • 将数组值与同一数组中的其他值进行比较

    我想要实现的是 它将循环遍历数组 然后它会检查数组中的项目在三个点上是否相同 product id 尺寸值和颜色值 我想创建一个新数组 其中列出了项目 我唯一不想要的是重复的值 我希望重复的值如果在这三个点上相同 则数量将被计算在一起 就像
  • 发送 QUERY 数据包时出错。 PID=9565

    我有两个不同的环境开发和生活几乎都是相同的 但上述 标题中 警告仅在开发模式下发生 在此警告之前 我还收到错误消息 允许的内存大小 268435456 字节已耗尽 这仅发生在开发模式下 使用 PHP 版本 5 6 和 mysql 不是 my
  • 使用 php 将 HTML 输出转换为纯文本

    我正在尝试将示例 HTML 输出转换为纯文本 但我不知道如何操作 我使用 file get contents 但我尝试转换的页面返回的结果最相似 raw http localhost guestbook profiles php file
  • 现实世界抽象类使用简单示例

    有没有使用抽象类的现实世界简单示例 我试图进入 PHP 的 OOP 但我仍然无法理解 为什么应该使用抽象类以及何时使用 是的 我知道不可能创建抽象类实例 只能创建继承它的类的实例 也许您有一个图像类 并且有 2 个驱动程序 GD 和 Ima
  • PHP 中使用 MVC 的 Post-Redirect-Get (PRG) 最佳实践

    PRG 模式与 MVC 是否有最佳实践 在本教程中 http www theserverside com news 1365146 Redirect After Post http www theserverside com news 13
  • 创建横幅交换算法来轮播广告

    我正在构建广告横幅轮播脚本基于印象整个月均匀地显示广告 每次请求显示广告时都会进行计算 所以这将是即时完成的 广告应显示为一个接一个轮流播放 而不是仅显示一个广告 1000 次展示 然后显示另一个广告 1000 次展示 大多数情况下 它应该
  • 如何在文本字段内设置用户名和密码的标签?

    我的网站有一个登录表单 该登录表单有两个文本字段 用户名和密码 目前 我将标签 用户名 密码 放置在文本字段之前 但现在我想删除这两个标签并想在文本字段内显示文本 用户名 密码 当用户关注这些文本字段时 文本应该被删除 用户可以输入他想要的
  • 如何在WAMPServer中启用或安装PHP的mysql_xdevapi扩展来安装数据表?

    我想在 laravel 中安装 DataTable 我使用了 WAMPServer 和我的 PHP version is 7 3 5 Mysql version 5 7 26 我按照互联网上的许多步骤操作 例如从 pecl php net
  • Laravel Eloquent 在 with() 函数中使用别名

    再会 laravel 中使用 with 函数时是否可以使用别名 举个例子 posts Post where condition gt with user as friend gt get 简短的回答是否定的 但您可以定义与要使用的别名的关系
  • 如何更新 mongodb PHP 中的所有文档

    我正在设置一个 cronjob 来更新该字段views 15关于集合中的所有文档query 这就是我所拥有的 应该有效 update array set gt array views 15 gt 0 db gt queries gt upd
  • 数组中的唯一条目

    我有以下内容将前 10 个 URL 存储到会话中 function curPageURL pageURL http if SERVER HTTPS on pageURL s pageURL if SERVER SERVER PORT 80
  • Symfony 3.4 没有元数据类来处理错误

    我已经安装了 symfony 3 4 和 学说包 php gt 5 5 9 doctrine doctrine bundle 1 8 doctrine doctrine migrations bundle 1 3 doctrine orm
  • PHP 警告:模块“imagick”已在第 0 行未知加载

    我有一个简单的测试文件 其中唯一的 php 代码是 if isset REQUEST back back back REQUEST back filename images back jpg file file exists filenam
  • 与 ssh2_connect() 断开连接

    我已经使用 ssh2 连接ssh2 connect到服务器 但我没有看到任何方法在联机帮助页中 http php net ssh2 connect我应该如何结束连接 我不太喜欢在断开连接之前等待脚本结束 我可以用吗fclose 这听起来不对
  • PHP - Paypal API 表单和安全性 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在我的电子商务应用程序上使用标准 php paypal 表单进行付款 我注意到只有 firebug 的人可以在通过 立即付款 按钮发
  • 在 Codeigniter 中添加表前缀以加入

    我设置了 Codeigniter 将前缀 kms 添加到我的活动记录查询中 但是 我尝试使用两个 ON 条件进行连接 但它不会将它们放在前面 现在我必须像这样手动添加它们 this gt db gt join site items kms
  • 在单个测试中断言多个条件,还是分成多个测试? [复制]

    这个问题在这里已经有答案了 如果您正在测试如下所示的计数函数 那么在一个函数中测试该函数的多项内容与为每个测试使用一个测试函数相比 是否被认为是 正确 或 错误 function testGetKeywordCount tester thi
  • mysql 查询从给定的表结构创建 SEO 友好的 url

    我正在尝试使用下表创建 SEO 友好的 URL 类别表 http sqlfiddle com 2 c474a 4 页表 http sqlfiddle com 2 c474a 5 我正在尝试编写一个 mysql 查询 该查询将使用产生以下输出

随机推荐

  • 在 UITableViewCell 中编辑 TextLabel [重复]

    这个问题在这里已经有答案了 可能的重复 如何在 UITableView 中进行就地编辑 https stackoverflow com questions 2803626 how to do edit in place in a uitab
  • 使用纯 JavaScript 创建、追加和提交表单

    我正在尝试实现 onclick 函数 该函数使用 POST 方法发送参数 我需要这个函数来重新加载页面 这使得我使用 AJAX 之外的其他方式 我有一个函数可以做到这一点 但这个函数使用 jQuery 现在我需要将其 移植 到纯 JavaS
  • 初始化函数破坏单元测试

    在我想要测试的包中 我有一个 init 函数 它加载配置文件 其中包含我想用来运行应用程序的一些内容 但是 我不想在运行单元测试时触发此初始化函数 有没有办法在单元测试期间跳过或阻止调用此 init 函数 一些片段来说明这个问题 func
  • 使用 SKAction colorizeWithColor 使 SKSpriteNode 闪烁白色

    好的 我有一个精灵 当被某物击中时应该会闪烁白色 我正在使用这个 SKAction changeColorAction SKAction colorizeWithColor SKColor whiteColor colorBlendFact
  • 使用 array_diff 时保留重复项

    我使用 array diff 从 array1 中取出在 array2 中找到的值 问题是它删除了 array1 中的所有出现项 正如 PHP 文档所指出的那样 我希望它一次只取出一个 array1 array array1 a array
  • 使用 haskell 构建动态库并从 C++ 中使用它

    我想构建一个包含 haskell 函数的动态库 我在 Linux 上工作 想从 C 代码中调用这个动态库 我用的例子是http wiki python org moin PythonVsHaskell http wiki python or
  • Java中如何检查抛出的异常类型?

    如果一个操作捕获了多个异常 如何确定捕获了哪种类型的异常 这个例子应该更有意义 try int x doSomething catch NotAnInt ParseError e if thrown error is NotAnInt li
  • 为什么 Google Analytics 使用 __utm.gif?

    只是想了解他们为什么不使用 REST API 在REST中 客户端向服务器发起资源请求 服务器处理这些请求并返回适当的响应 The utm gif不参与服务器到客户端的数据传输 而是参与向另一个方向移动数据 当然 REST 具有供客户端与服
  • 是否可以将公共IP分配给AWS中的Lambda函数?

    我们需要访问企业后端中的 API 该 API 仅接受来自授权 IP 地址的调用 此时 我们的移动客户端正在调用 AWS Lambda 函数 该函数执行一些转换 然后调用分配了授权公共 IP 地址的 EC2 实例上的另一个服务 第二个服务执行
  • SQLite数据适配器不显示数据

    我试图在 Windows 窗体应用程序中填充数据网格视图 但当我执行选择查询时 数据库没有返回任何内容 我已经在本网站上查看了有关此主题的其他问题 但找不到任何可以解决我的问题的内容 数据视图表的名称是qbcMemDataView 数据源是
  • 如何使用 Java 中的 Scanner 将输入值存储在数组中

    您好 我是 Java 新手 我正在尝试 Scanner 类 我试图解决一个小问题 我想输入两个输入 例如 4 5 6 和 8 9 0 我想将 4 5 6 存储在一个数组中 将 8 9 0 存储在另一个数组中 然后打印这些数组 但我无法这样做
  • “:=”有什么作用?

    我见过 在多个代码示例中使用 但从未附带说明 如果不知道它的正确名称 就不可能通过谷歌搜索它的用途 它有什么作用 http en wikipedia org wiki Equals sign In computer programming
  • Gitolite 权限仅限于一个分支

    我有点困惑gitolite https gitolite com gitolite 权限 仅允许 1 个分支并拒绝特定用户或组的所有其他分支的最佳方法是什么 See 部分复制 分支的选择性读取控制 https gitolite com gi
  • 从列表转换为数字

    我正在从列表形式强制转换为数字形式 如果有用的话 列表最初是从一个因素中绘制的 并且是 1x33 行 我的列表定义为 tmpseqsf 1 其中规定 TradeValue 1 72914431 2 25325 3 20139 4 因此 根据
  • 与基于类的方法相比,使用 Hooks 设置状态后重新渲染有什么区别?

    类组件 在 React 类组件中 我们被告知setState always导致重新渲染 无论状态是否实际更改为新值 实际上 一个组件will当状态更新到时重新渲染same以前的价值 文档 setState API 参考 https reac
  • ViewPager内部的TextView拦截触摸事件

    我有一个ViewPager包含两个片段 在任何片段中我都可以触摸一个地方 滑动即可切换到另一个地方fragment 其中一个片段包含一个列表 列表中的项目包含一项TextView和一个ImageView 问题是 如果您是从点击开始拖动的Im
  • 未定义的索引:php 脚本中的错误

    在 php 页面中我有以下代码 if REQUEST c I get error on this line itself Why pidis int REQUEST c 我不断收到未定义索引错误 在谷歌搜索上 我设法理解 如果我们尝试访问的
  • Visual Studio 设置以在运行时删除对 dll 文件的依赖

    到处都有人建议当 Visual Studio 在运行时找不到 DLL 时如何让 Visual Studio 知道 但我想知道在哪里删除该选项 以便 Visual Studio 在运行时不会尝试查找 dll 文件 我昨天也有类似的问题 但没有
  • Spring XML 406错误

    我正在尝试使用 Java 制作 RESTful 服务 使用多个教程和许多 StackOverflow 条目 不幸的是 我似乎无法让我的代码工作 当我尝试到达端点时 我一直收到 Http 406 任何帮助表示赞赏 GreetingContro
  • 工厂中的依赖注入

    我对 DI 很陌生 但我真的很想尝试使用它 有件事我不明白 这是一个简单的工厂伪代码 我经常使用 class PageFactory public function construct dependency list save refere