I have recently come across the SOLID design principles and have been looking to find ways to incorporate dependency injection into my work so that I can write better tests and mock out any external calls. I have had a go at some dependency injection in PHP Laravel (Lumen) but something doesn't seem right in the below.
The code to create the dependencies is being created inside a public method in one of the controllers. This doesn't seem like the appropriate place to put it as I now have a lot of quite ugly code instantiating objects inside the controller rather than just receiving the request and packaging up the response. Is there somewhere more appropriate to the do the instantiation? Also for certain items, e.g. the $paying_user object. I am creating an empty Eloquent model, using a method to retrieve the first item in a collection and swapping it with the returned object to inject. This doesn't feel right either. Can anyone point me in what the best and proper way to structure the below should be?
public function cancel_subscription(Request $request)
{
$result = false;
// Create dependencies
$platform_id = Sanitiser::clean_integer($request->input('platform_id'));
$paying_user = new PayingUserModel();
$paying_user = $paying_user->where('platform_id','=',$platform_id)->first();
$current_subscription_model = $paying_user->non_cancelled_subscriptions->first();
$refund_model = new RefundModel();
$stripe = new Stripe();
$stripe_refund = new Refund();
$charge = new ChargeModel();
$stripe::setAPIkey(env('STRIPE_SK'));
$stripe_subscription = new Subscription();
// Create services and inject
$this->cancellation_service = new CancellationService($paying_user,$current_subscription_model,$stripe_subscription);
$this->refund_service = new RefundService($paying_user,$current_subscription_model,$refund_model,$stripe_refund,$charge);
// Run services
$result = $this->cancellation_service->cancel_subscription();
if($this->cancellation_service->get_refund_required()==true){
$result = $this->refund_service->handle_refund();
}
}