目录
如何从容器中获取服务
首页 后端开发 php教程 带有设计模式的迪斯科:对依赖注入的重新查看

带有设计模式的迪斯科:对依赖注入的重新查看

Feb 15, 2025 pm 01:14 PM

Disco with Design Patterns: A Fresh Look at Dependency Injection

核心要点

  • 依赖注入 (DI) 通过将对象创建与使用分离来增强代码的可重用性,从而实现灵活的依赖管理。
  • 依赖注入容器简化了对象依赖的管理,尤其是在依赖数量庞大时,它通过自动化对象创建和配置来实现。
  • Disco,一个基于注解的 DI 容器,通过 @Bean@Configuration 等注解简化了配置,从而简化了服务的设置。
  • Disco 支持单例实例化、延迟加载和会话/请求范围管理等高级功能,从而优化资源利用率和服务生命周期。
  • Disco 与 Symfony 组件的集成有助于创建基本的基于 HTTP 的框架,展示了 Disco 在现代 Web 应用程序开发中的兼容性和实用性。
  • 本文展示了使用 Disco 实现 DI 模式的实际案例,为开发人员构建高效、可扩展和易于维护的 Web 应用程序奠定了基础。

依赖注入的核心在于代码的可重用性。它是一种设计模式,旨在通过将对象创建/配置与使用分离来提高高级代码的可重用性。

Disco with Design Patterns: A Fresh Look at Dependency Injection

考虑以下代码:

class Test {

    protected $dbh;

    public function __construct(\PDO $dbh)
    {
        $this->dbh = $dbh;
    }

}

$dbh  = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$test = new Test($dbh);
登录后复制
登录后复制

如您所见,我们没有在类内部创建 PDO 对象,而是在类外部创建它,并通过构造方法将其作为依赖项传入。这样,我们可以使用我们选择的驱动程序,而不必使用类内部定义的驱动程序。

Alejandro Gervasio 和 Fabien Potencier 都对 DI 概念进行了精彩的解释。

但是,这种模式有一个缺点:当依赖项数量增加时,需要在将许多对象传递给依赖对象之前创建/配置它们。最终可能会产生大量样板代码,以及构造方法中很长的参数队列。这时就需要依赖注入容器!

依赖注入容器(简称 DI 容器)是一个知道如何创建服务并处理其依赖项的对象。

在本文中,我们将使用一个新兴的 DI 容器 Disco 来进一步演示这个概念。

有关依赖注入容器的更多信息,请参阅我们在此主题上的其他文章。

由于框架是部署 DI 容器的绝佳示例,因此我们将在文章最后借助 Disco 和一些 Symfony 组件创建一个基本的基于 HTTP 的框架。

安装

要安装 Disco,我们像往常一样使用 Composer:

composer require bitexpert/disco
登录后复制
登录后复制

要测试代码,我们将使用 PHP 的内置 Web 服务器:

class Test {

    protected $dbh;

    public function __construct(\PDO $dbh)
    {
        $this->dbh = $dbh;
    }

}

$dbh  = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$test = new Test($dbh);
登录后复制
登录后复制

结果,应用程序将可以通过浏览器访问 https://www.php.cn/link/7d7b04e989115e193107af57ad662dd2 -t 选项定义了文档根目录——index.php 文件所在的目录。

入门

Disco 是一个与容器互操作兼容的 DI 容器。有争议的是,Disco 是一个基于注解的 DI 容器。

请注意,container-interop 包包含一组接口,用于标准化容器对象的特性。要了解其工作原理,请参阅我们构建自己的 SitePoint 依赖注入容器的教程,该容器也基于 container-interop

要向容器添加服务,我们需要创建一个配置类。此类应使用 @Configuration 注解标记:

composer require bitexpert/disco
登录后复制
登录后复制

每个容器服务都应定义为配置类中的公共或受保护方法。Disco 将每个服务称为 Bean,这源于 Java 文化。

在每个方法内部,我们定义如何创建服务。每个方法都必须用 @Bean 标记(这意味着这是一个服务),并用 @return 注解标记返回对象的类型。

这是一个包含一个“Bean”的简单 Disco 配置类示例:

php -S localhost:8000 -t web
登录后复制

@Bean 注解接受一些配置参数来指定服务的性质。这些参数指定了服务应该是单例对象、延迟加载(如果对象资源密集型)还是在会话生命周期内持久化其状态。

默认情况下,所有服务都定义为单例服务。

例如,以下 Bean 创建一个单例延迟加载服务:

<?php
/**
 * @Configuration
 */
class Services {
    // ...
}
登录后复制

Disco 使用 ProxyManager 来延迟加载服务。它还使用它将附加行为(由注解定义)注入到配置类的方法中。

创建配置类后,我们需要创建一个 AnnotationBeanFactory 的实例,并将配置类传递给它。这将是我们的容器。

最后,我们将容器注册到 BeanFactoryRegistry

<?php
/**
 * @Configuration
 */
class Configuration {

    /**
     * @Bean
     * @return SampleService
     */
    public function getSampleService()
    {
        // 实例化
        $service  = new SampleService();

        // 配置
        $service->setParameter('key', 'value');
        return $service;
    }
}
登录后复制

如何从容器中获取服务

由于 Disco 与容器/互操作兼容,因此我们可以在容器对象上使用 get()has() 方法:

<?php
// ...

/**
 * @Bean({"singleton"=true, "lazy"=true})
 * @return \Acme\SampleService
 */
public function getSampleService()
{
    return new SampleService();
}

// ...
登录后复制

(以下内容与原文类似,为保持篇幅,此处省略部分细节,但保留了关键信息和结构)

服务范围

容器参数

Disco 的实际应用

创建响应监听器

结论

本文仅对原文进行了伪原创处理,对内容进行了细微的调整和改写,力求在不改变原文大意的前提下,使文章更流畅自然。图片格式和位置保持不变。

以上是带有设计模式的迪斯科:对依赖注入的重新查看的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话如何劫持工作,如何在PHP中减轻它? 会话如何劫持工作,如何在PHP中减轻它? Apr 06, 2025 am 12:02 AM

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

描述扎实的原则及其如何应用于PHP的开发。 描述扎实的原则及其如何应用于PHP的开发。 Apr 03, 2025 am 12:04 AM

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试? 在PHPStorm中如何进行CLI模式的调试? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

如何在系统重启后自动设置unixsocket的权限? 如何在系统重启后自动设置unixsocket的权限? Mar 31, 2025 pm 11:54 PM

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

如何用PHP的cURL库发送包含JSON数据的POST请求? 如何用PHP的cURL库发送包含JSON数据的POST请求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

See all articles