php di 使用,PHP-DI和依赖注入的最佳实践

PHP-DI是用 PHP 编写的、强大的和实用的、框架无关的依赖注入容器。这是一个关于如何使用PHP-DI和依赖注入的最佳实践指南。

文章来源于PHP-DI,作者:Matthieu Napoli和贡献者。PHP-DI是用 PHP 编写的、强大的和实用的、框架无关的依赖注入容器。

这是一个关于如何使用PHP-DI和依赖注入的最佳实践指南。

虽然它可能不包括每个案例,并满足每个人,但它可作为抛砖引玉,以帮助您开始依赖注入。

如果你不同意该指南中解释的任何内容,那没关系。你应该对这些问题提出自己的见解:)。它不会阻止你以你想要的方式使用PHP-DI。

使用容器和依赖注入的规则

以下是一些基本规则:

不要直接从容器中获取一个条目(总是使用依赖注入)

更普遍的是,编写代码解耦的容器

针对接口的类型约束,要在容器的配置中配置使用哪种实现

#编写控制器

在控制器中使用依赖注入通常是最痛苦的。

如果我们以Symfony 2为例(但这通常适用于每个框架),这里有你的选择:

在容器中注入控制器,并调用 $container->get(...)

这是不好的,见规则n°1。

在构造函数中注入依赖性(在Symfony中作为服务的控制器)

这是痛苦的,当你有5个以上的依赖项,你的构造函数是15行样板代码

在属性中注入依赖性

这是我们建议的解决方案。

例如:

class UserController

{

/**

* @Inject

* @var FormFactoryInterface

*/

private $formFactory;

public function createForm($type, $data, $options)

{

// $this->formFactory->...

}

}

如你所见,这个解决方案需要很少的代码,很容易理解和利于IDE支持(自动完成,重构,...)。

属性注入通常让人皱眉头,这是有一定的原因的:

注入私有属性破坏了封装

它不是一个显式的依赖:没有约定,说你的类需要设置属性以工作

如果使用PHP-DI的注解来标记要注入的依赖关系,那么您的类依赖于容器(请参见上面的第2条规则)

如果您遵循关于如何编写应用程序的一般最佳实践,您的控制器将不包含业务逻辑(仅对模型进行路由调用并绑定返回的值以查看)。

因此:

你不会对它进行单元测试(这并不意味着你不会在接口上写功能测试)

你不需要在别处重用它

如果你改变框架,你可能不得不重写它(或其部分)(因为大多数依赖,如请求、响应、模板系统等将改变)

此解决方案提供了许多优点,没有主要的缺点,因此我们建议在控制器中使用注解。

编写服务

给定一个服务旨在被重用、测试和独立于你的框架,我们不建议使用注解注入依赖。 相反,我们建议使用构造函数注入和自动装配:

class OrderService implements OrderServiceInterface

{

private $paymentService;

public function __construct(PaymentServiceInterface $paymentService)

{

$this->paymentService = $paymentService;

}

public function processOrder($order)

{

$this->paymentService->...

}

}

通过使用自动装配(默认情况下启用),您自己保存绑定配置中的构造函数的每个参数。 PHP-DI将通过检查您的参数的类型来猜测它需要注入哪个对象。

在某些情况下,使用自动装配还不够,因为一些参数将是一个标量(string,int,...)。 此时,您需要明确定义要在该标量参数中注入的内容,为此,您可以:

定义方法/类的全部注入(即,每个参数)。

例如:

// ...

OrderService::class => DI\object()

->constructor(DI\get(SomeOtherService::class), 'a value'),

];

或者只定义标量参数,让PHP-DI使用自动装配。

例如:

// ...

OrderService::class => DI\object()

->constructorParameter('paramName', 'a value'),

];

这个解决方案通常是优选的,避免重新定义一切。

旁注:如规则n°3中所述,我们建议对接口进行类型约束。 在这种情况下,您将需要将接口映射到容器在配置中应该使用的实现:

使用库

当使用库,如日志记录器,ORM,...有时需要配置它们。

在这种情况下,我们建议您在配置文件中定义这些依赖关系。 我们还建议在配置有点复杂时使用匿名函数。

匿名函数允许你编写真正的PHP代码,这是伟大的,因为你可以使用库的文档,得到IDE支持,作为一个PHP开发人员,你懂的:)。

这里是一个例子,Monolog,一个PHP记录器:

use Monolog\Logger;

use Monolog\Handler\StreamHandler;

return [

// ...

Psr\Log\LoggerInterface::class => DI\factory(function () {

$logger = new Logger('mylog');

$fileHandler = new StreamHandler('path/to/your.log', Logger::DEBUG);

$fileHandler->setFormatter(new LineFormatter());

$logger->pushHandler($fileHandler);

return $logger;

}),

];

当然,如你所见,我们使用PSR-3接口进行注入。 这样,我们可以随时用任何PSR-3记录器替换Monolog,只需更改此配置即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值