a2workspace / laravel-automount
使依赖注入更简单
v1.1.0
2022-09-04 08:47 UTC
Requires
- php: ^7.4|~8.0
Requires (Dev)
- orchestra/testbench: 4.x
This package is auto-updated.
Last update: 2024-09-04 13:38:09 UTC
README
随着PHP 8的新特性增加,你可能已经不需要此套件了,可参考构造函数属性提升的做法
Laravel的依赖注入很棒,但我们让它更好!
关于
想想看,当你项目越来越大,一定有遇到过又臭又长的构造函数:
use A2Workspace\AutoMount\AutoMountDependencies; class ProductController extends Controller { protected ProductService $productService; protected ProductRepository $productRepository; protected ProductStockManager $productStockManager; public function __construct( ProductService $productService, ProductRepository $productRepository, ProductStockManager $productStockManager ) { $this->productService = $productService; $this->productRepository = $productRepository; $this->productStockManager = $productStockManager; } public function __invoke(Request $request) { $this->productService->doSomething(); } }
通过AutoMountDependencies
特性自动挂载依赖,让我们省略复杂的绑定过程。
use A2Workspace\AutoMount\AutoMountDependencies; class ProductController extends Controller { use AutoMountDependencies; // Add this. protected ProductService $productService; protected ProductRepository $productRepository; protected ProductStockManager $productStockManager; // We don't need the constructor anymore... public function __invoke(Request $request) { $this->productService->doSomething(); // Still works! } }
安装
此套件基于PHP 7.4的类型属性新功能,请确保你的PHP更新到最新版本。
composer require a2workspace/laravel-automount
如何使用
只需在目标类上使用AutoMountDependencies
特性
use A2Workspace\AutoMount\AutoMountDependencies; class PaymentService { use AutoMountDependencies; }
接下来,有类型定义的类属性就会在构造时自动进行依赖注入。
use A2Workspace\AutoMount\AutoMountDependencies; class PaymentService { use AutoMountDependencies; protected PaymentGatewayFactory $factory; }
注意:考虑到继承,请避免在要被处理的属性上使用private
私有。
不会被处理的属性
以下类型的属性会被忽略处理
- 基本类型(int, float, bool, array ...)
- 未定义类型的属性
- 定义为可空的属性
- 有初始值的属性
use A2Workspace\AutoMount\AutoMountDependencies; class PaymentService { use AutoMountDependencies; protected int $amount; // Pass. protected array $gateways; // Pass. protected $something; // Pass. protected ?PaymentGateway $gateway = null; // Pass. protected PaymentGatewayFactory $factory; // Do inject. }
限制
覆盖构造函数
AutoMountDependencies
特性中定义了在构造函数中执行依赖挂载的动作。当你需要覆盖__construct()
时,记得手动调用mountDependencies()
方法。
use A2Workspace\AutoMount\AutoMountDependencies; class PaymentService { use AutoMountDependencies; public function __construct() { $this->mountDependencies(); // Add this line. // ... } }
避免私有属性
当类型属性被定义为私有,会导致继承后的子类,在构造时无法写入属性而造成错误。
请谨慎使用private
,或将属性定义为可空。
use A2Workspace\AutoMount\AutoMountDependencies; abstract class BasePaymentGateway { use AutoMountDependencies; private PaymentServiceProvider $service; } class PaymentGateway extends BasePaymentGateway { // ... } $gateway = new PaymentGateway; // 拋出 PaymentGateway::$service 未被初始之錯誤