现实生活中的依赖注入

2024-01-01

我正在构建一个非常小的 MVC 框架来增加我的 PHP 知识并挑战自己。我已经到了类开始相互依赖才能工作的地步。依赖注入 http://fabien.potencier.org/article/11/what-is-dependency-injection似乎是这个问题的解决方案,并被一些人使用大框架 http://components.symfony-project.org/dependency-injection/大约。

我发现了Bucket https://github.com/troelskn/bucket在 Github 上,并且已经搞砸了一段时间来了解基础知识。然而,我无法理解的是何时适合创建容器?

制作一个大容器,其中包含所有可能的类可能需要对我来说似乎只会适得其反,我无法想象这是一个好的做法。至少这似乎是导致糟糕表现的原因。

另一种方法是制作多个容器,我仍然不明白为什么不再需要那些令人讨厌的单例。

假设我有以下代码:

$session_container = new bucket_Container();
$session_container->create('Database');
$session_container->create('Database_Sessions');

$log_container = new bucket_Container();
$log_container->create('Database');
$log_container->create('Database_Log');

所以这里我们有两个容器,或者在本例中buckets对于两种完全不同的用法,它们通过依赖于Database class.

我的逻辑告诉我,上面的代码将创建两个独立的实例Database-class,这意味着我仍然需要做Database-对单例进行分类以确保不会发生数据库连接的并发实例?

它是否正确?


我对具体的库了解不多,但假设它允许您使用工厂,让工厂返回相同的实例。

编辑:好的,这只是在 Bucket GitHub 索引页面上。

class MyFactory {
  function new_PDO($container) {
    return new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
  }
}

$bucket = new bucket_Container(new MyFactory());
$db = $bucket->get('pdo');

因此,就您而言,您可以简单地执行以下操作:

class MyFactory {
   private $pdo;
   function new_Database($container) {
     if($this->pdo){
         return $this->pdo;
     }
     return $this->pdo = new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
   }
}
$factory = new MyFactory();

$session_container = new bucket_Container($factory);
$session_container->create('Database_Sessions');

$log_container = new bucket_Container($factory);
$log_container->create('Database_Log');

类似的事情。看起来不像火箭科学。

Edit2:我没有足够的代表点来评论这个问题(有点傻),但为了回应您的“模块化”问题:将容器视为应用程序的“粘合剂”。事实上,如果您有一个大型应用程序,您可能只想“粘合”在应用程序的隔离部分内。这是一个有效的封装问题。但即便如此,您仍然需要一个在最高抽象级别处理注入的容器。如果您只是为应用程序的每个部分创建一个单独的容器,那么您要么会得到不必要的实例重复,要么必须应用另一级别的实例管理,这不会以任何方式改进封装:您仍然在应用程序的不同部分之间共享实例。

我的建议是在引导级别使用单个容器。如果您想为应用程序的特定部分(模块、插件等)添加封装,请使用“子容器”。子容器从父容器继承实例,但父容器对子容器一无所知(就他而言,他仍然是一个单身汉;))。可能是 Bucket 默认支持这个,我知道其他 DI 容器也支持。如果没有,使用装饰器实现起来真的很容易。想象一下这样的事情:

class MyContainerType extends bucket_Container {

    private $_parent;
    private $_subject;

    public function  __construct($factory = null, bucket_Container $parent = null){
        $this->_parent = $parent;
        $this->_subject = new bucket_Container($factory);
    }

    public function get($key){
        $value = $this->_subject->get($key);
        if($value){
            return $value;
        }
        return $this->_parent->get($key);
    }
    /**
     * Override and delegation of all other methods
     */
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

现实生活中的依赖注入 的相关文章

  • curl 无法获取网页内容,为什么?

    我正在使用curl 脚本转到链接并获取其内容以进行进一步操作 以下是链接和curl脚本
  • 创建 AoT 兼容的服务工厂

    我正在尝试为缓存服务创建一个服务工厂 主要要求是每次可以使用不同的字符串实例化单个服务 最终的结果会有多个cache每个服务都由唯一定义databaseName 每个缓存可以有一个或多个stores也由唯一定义storeName 其他服务将
  • 未找到“MongoId”类(带有 MongoDB Doctrine 的 Zend 框架)

    我目前正在尝试将 MongoDB 与 ZendFramework 中的 Doctrine 集成 我做了很多教程 在 StackOverflow 或其他地方 但没有任何效果 我一步步按照教程进行操作 http www bigwisu com
  • 匹配括号内任何字符的正则表达式

    尝试创建一个与括号内的任何字符匹配的正则表达式 我的正则表达式模式是这样的 preg match listanswer answer 括号内的所有字符串都是匹配模式 但问题是 当我尝试匹配例如 this word sample data 它
  • cakephp 1.1 与 php 5.3

    我刚刚从 php 5 1 升级到 5 3 之前在我的服务器上使用 cakephp 1 1 自从升级 或者可能更早 我不确定 以来 我收到以下错误 任何人都可以透露一些信息 Deprecated Assigning the return va
  • json_encode 创建格式错误的 JSON 数据?

    我有一个 codeigniter 应用程序将一些数据从数据库返回到视图 我正在尝试将其作为 json 数据发送回来 问题是返回的数据格式错误 它看起来像这样 2 5 Admin1 2 10 Admin2 当我在 jsonlint com 上
  • 如何将 .env 添加到 codeigniter?

    我尝试按照以下步骤使 php 连接到 Outlookhttps learn microsoft com en us outlook rest php tutorial https learn microsoft com en us outl
  • HTTP_REFERER 返回 NULL,$_SERVER 中不存在密钥

    使用以来第一次 SERVER HTTP REFERER 它给了我NULL因此 当我做var dump SERVER the HTTP REFERER密钥不存在 我还尝试使用不同的浏览器和不同的网站访问网站 但没有结果 该网站在基于 Linu
  • 如何在 Laravel Mix 中将公共路径更改为包含下划线的路径?

    Laravel 5 4 中引入了 Mix 来编译资产并维护资产管道 Mix 默认为您的公共目录被命名public 在许多情况下 包括我的 我的公共目录被称为其他名称 就我而言 是public html 如何更改资源编译到的公共目录 我尝试过
  • Laravel 5.6 - 注册表无法正常工作并且不显示任何错误

    在我最近的一个项目中 定制登记表不管用 当我单击注册按钮时 它会重新加载注册表单 不会打印任何错误 并且不会将数据插入数据库中 这是注册表的外观 这里是移民文件代码 public function up Schema create user
  • 在 Laravel 中按数据透视表 create_at 排序

    在我的数据库中 我有以下表格 courses id 名称 创建时间 更新时间 students id 名称 创建时间 更新时间 课程 学生 id course id student id created at updated at 我正在尝
  • MySQL:“您的 SQL 语法错误...靠近键...”? [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我发现了一个非常酷的用于丢失密码的脚本 但是这一行给我带来了问题 r mysql query INSERT INTO keys u
  • Lumen 微框架 => php artisan key:generate

    我正在尝试 PHP 微框架 Lumen 来自 Laravel 我的第一步就是调查 env example文件并复制一份以供我使用 env文件 就像 Laravel 中一样 有一个变量 APP KEY 现在我尝试了简单的命令php artis
  • 如何在PHP中将图像从内存上传到AWS S3?

    所以我目前有一个使用 AWS S3 上传图像的上传系统 这是代码 Upload image to S3 s3 Aws S3 S3Client factory array key gt mykey secret gt myskey try s
  • 计算轮班工作时间并检测

    我有个问题 我的英语很差 我需要用PHP做一个加班计算 已经有一个代码可以实现这一点 但当工作时间超过2天时 计算就会出错 工作开始 2018 09 09 13 43 工作结束 2018 09 11 07 13 结果 07 18 04 00
  • 过程式编程与 OOP 的开发成本?

    我有相当深厚的 OO 背景 OOD 和 OOP 的好处对我来说是第二天性 但最近我发现自己在一家与过程编程习惯相关的开发商店 实现语言具有一些 OOP 功能 但它们没有以最佳方式使用 更新 每个人似乎对这个话题都有自己的看法 我也是如此 但
  • Apache 2.4.9 在启用 ssl 模块并设置 ssl 证书后失败

    Apache 在尝试设置 ssl 证书后抛出以下错误 ssl emerg pid 30907 AH02572 Failed to configure at least one certificate and key for localhos
  • PHPunit - 错误

    当 PHPunit 框架不希望发生的错误发生时 测试会停止 PHP 会抛出错误 但 PHPunit 不会记录这是一个错误 我如何确保 PHPunit 将其记录为错误 免责声明 我是 PHPUnit 的新手 我也试图弄清楚 发生错误时会发生什
  • PHP 用星号替换所有字符

    假设我有一个字符串形式的密码 password thisisaplaintextpassword 我怎样才能把它变成下面的样子 password 我想通过电子邮件向用户发送他们的帐户详细信息 但不想发送整个内容 Use 字符串重复 http
  • 使用 md5 加密的 PHP 和 Mysql 查询出现问题

    我使用普通的 php mysql 插入查询并使用 md5 加密密码 这是插入查询 sql mysql query INSERT INTO user username password role approved values usernam

随机推荐