framework
framework copied to clipboard
[12.x] Introduce `#[Proxy]` attribute
allow users to mark classes or dependencies which should be built lazily
Building off of @timacdonald's work in https://github.com/laravel/framework/pull/57831/
Why would anyone need this
If you've worked in a legacy project, you might've come across junk-drawer service classes that look like this:
class PaymentService
{
public function __construct(
public CustomerService $customerService,
public StripeService $stripeService,
public PayPalService $paypalService,
public XeroService $xeroService,
public ReceiptService $receiptService
// .... imagine 10 more services
) {}
// imagine 10 functions, spread out across 1500 lines of code, none of which use all the dependencies
public function getStripeCustomer(Customer $customer): StripeCustomer
{
return $this->stripeService->getCustomerByEmail($customer->email);
}
}
When I call PaymentService@getStripeCustomer(), I am constructing all of the dependencies just to call one of them.
In an ideal world, this would be refactored into smaller components with fewer dependencies in each. That's not always a price a development team can pay all at once.
To simplify this, I am proposing introducing a #[Lazy] attribute, which can be applied to either a class or individual parameters.
class PaymentService
{
public function __construct(
#[Lazy] public CustomerService $customerService,
#[Lazy] public StripeService $stripeService,
// ...
) {}
}
Naming
Technically this is built using the proxy() function. I'm not sure that naming the attribute something other than Lazy is worth the distinction.
Other ideas
Adding a parameter bool $dependencies that would also make all of the dependencies lazy for the class