Take the following code as an example of what i want:
class SomethingController extends Factory
{
private $somethingRepository;
public function __Construct( ISomethingRepository $repo )
{
$this->somethingRepository = $repo;
}
}
class Factory
{
public function __Construct()
{
// The following call to AddBinding would push into SomethingController the new instance of the class denoted in my AddBinding second parameter.
$this->AddBinding( ISomethingRepository, MySQLSomethingRepository);
// So in this case, if the controller i'm extending has a construct parameter of ISomethingRepository, then make the parameter equal a new MySQLSomethingRepository()
// Then if I want to use JSONSomethingRepository in the future, I only have to change the one AddBinding call and the controller will still work.
}
public function AddBinding( $interface, $concrete )
{
// Somehow assign the constructor properties of the extending class as new instances of the bindings i have called upon in the construct of my factory class (see this class's construct)
// Pseudo code:
// ----------------------
$calledClass = get_called_class();
$class = new \ReflectionClass( $calledClass );
$method = $class->getMethod( "__construct" );
$params = $method->getParameters();
foreach( $params as $param )
{
if ( $param == $interface )
{
return new $concrete;
}
}
// /Pseudo code:
// ----------------------
}
}
I want to implement a factory kind of class.
This factory class will be extended by a controller class.
the factory class will look at the construct parameters of the controller class and make new instances of the object based off of my AddBindings method in the factory.
Let's say I wanted to have a MySQLSomethingRepository which has data coming from MySQL... injected into my SomethingController... Somewhere I need to declare that
SomethingController( new MySQLSomethingRepository() )...
which hopefully will be dealt with by my factory class...
The current way i'm doing it is that is forcing a direct coupling with the data source... which is making it very hard to do test cases with:
private $somethingRepository = new MySQLSomethingRepository();
so imagine if i have used this same repository in loads of other controllers and i want to change my database source to some json data and i implement the following repository "JsonSomethingRepository", I have to go and change all of the controllers to:
private $somethingRepository = new JsonSomethingRepository();
How might i implement my Factory class so that it can deal with creating the instances my controller class is demanding inside the AddBindings function?
Design an abstract class in Adapter model and provide some common methods for child class.
You can design both repos with adapters to injected in you controllers.
My recommendtation is to use Abstract class and do it in way below:
class SomethingController extends AbstractController {
}
abstract class AbstractController {
protected $somethingRepository;
public function __Construct(ISomethingRepository $repo) {
$this->somethingRepository = $repo;
$this->AddBinding ( ISomethingRepository, MySQLSomethingRepository );
}
public function AddBinding($interface, $concrete) {
// Somehow assign the constructor properties of the extending class as new instances of the bindings i have called upon in the construct of my factory class (see this class's construct)
}
}
Hope it would be help.
Related
I have an application which is built on top of another framework. Said framework has a number of value objects, which I need to extend in various ways using the decorator pattern. Lets call the base object Entity and the decorator classes Wrappers. Entities of the same class can have different "types", and a different Wrapper class is required for each of these types to expose functionality specific to that type. This application is not the final layer and does not control what types exist or which classes to use for them (done higher up the chain), so assignment needs to be dynamic.
I have created a factory class that receives an entity and determines the correct wrapper for it. The factory can be assigned a Wrapper class to be used when the entity is of a given type.
<?php
class WrapperFactory
{
protected $default_wrapper = null;
protected $typed_wrappers = [];
public function __construct($default){
$this->setDefaultWrapper($default);
}
public function setDefaultWrapper($class){
if ($this->validateWrapperClass($class)){
$default_wrapper = $class;
}
}
public function getDefaultWrapper(){
return $this->$default_wrapper;
}
public function setWrapperForType($class, $type){
if($this->validateWrapperClass($class)){
$this->$typed_wrappers[$type] = $class;
}
}
public function hasWrapperForType($type){
return array_key_exists($type, $this->typed_wrappers);
}
public function getWrapperForType($type){
if($this->hasWrapperForType($type)){
return $this->typed_wrappers[$type];
}
else{
return $this->getDefaultWrapper();
}
}
public function wrap($entity)
{
$class = $this->getWrapperForType($entity->type);
return new $class($entity);
}
protected function validateWrapperClass($class){
if(class_exists($class) && class_implements($class, WrapperInterface::class)){
return true;
}else{
throw new BadMethodCallException("Wrapper must implement ". WrapperInterface::class . ".");
}
}
}
I'm not entirely sure how to properly Unit Test this class. Is there a way I can mock a class that implements the interface, rather than an object? how can I test that an class assigned to a type is working properly? Do I need to explicitly declare a dummy class or two in my test files or is there a way to mock them?
If you create a Mock object, PHPUnit will create a class that extends the class you created the mock for. Because this works with interfaces as well, you can simply create a mock of your interface and get its class name:
$mock = $this->getMock('WrapperInterface');
$class = get_class($mock);
$this->assertTrue($factory->validateWrapperClass($class));
I have made a class. The class's constructor assigns a value to a class property.
Here is the definition:
class myClass
{
private $_value;
function __construct ($input)
{
$this->_value = $input;
}
function echoThat ()
{
echo $this->_value;
}
}
And the regular usage is:
$x = new myClass("SimpleString");
$x->echoThat();
But I have turned the class into a facade type of class in Laravel so it is used:
myClass::echoThat();
How should I utilize the __construct() method in Laravel Facades like the above example?
You should only create a Laravel facade if you really want to use your class like Laravel facades are used. Laravel facades provide a static interface to a class.
This means either rewrite your class so that you can pass your string in anyother way like:
MyClassFacade::echoThat('SimpleString');
Of course you can also modify the underlying class to use for example another method to pass the string:
class MyClass
{
private $_value;
public function setValue($val)
{
$this->_value = $val;
return $this;
}
public function echoThat()
{
echo $this->_value;
}
}
And then call it like:
MyClassFacade::setValue('SimpleString')->echoThat();
You can call the non static methods of you class "statically" if you instantiate your class wherever the Laravel facade accessor is resolved, for example in the service provider:
use Illuminate\Support\ServiceProvider;
class MyClassServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('myclass', function()
{
return new MyClass();
});
}
}
Laravel will create an instance of MyClass whenever a method on your class is called statically using __callStatic.
Or don't use the Laravel facade and instantiate your class manually like you did it:
$x = new myClass("SimpleString");
$x->echoThat();
You have first to understand that a Facade, in Laravel, is not really your class, you must look at it, as the name says, a forefront or a frontage to your class. Facade is, acually, a Service Locator to your class.
To use this Service Locator you have to create a Service Provider, which will provide the service used by the Facade:
<?php namespace App\MyApp;
use Illuminate\Support\ServiceProvider;
class MyClassServiceProvider extends ServiceProvider {
protected $defer = true;
public function register()
{
$this->app['myclass'] = $this->app->share(function()
{
return new MyClass('the values you need it to instantiate with');
});
}
public function provides()
{
return array('myclass');
}
}
Note that your class is instantiated in the method register() and now is available to your application via the IoC container, so you can do things like:
App::make('myclass')->echoThat();
And now you can also create your Facade to use it:
<?php namespace App\MyApp;
use Illuminate\Support\Facades\Facade as IlluminateFacade;
class ExtendedRouteFacade extends IlluminateFacade {
protected static function getFacadeAccessor()
{
return 'myclass';
}
}
The Facade has only one method and its only purpose is to return the name of your class instance in the IoC container.
Now you can open your app/config/app.php and add the ServiceProvider:
'App\MyApp\MyClassServiceProvider',
also the actual Facade alias:
'MyClass' => 'App\MyApp\MyClassFacade',
and you should be good to use your Facade:
echo MyClass::echoThat();
But note that the way it is made your class __constructor will be always called with the same parameters, in your ServiceProvider, that's how a Facade works, but you have some options:
Use a setter to set a new value for the data in your class instance.
public function setValue($value)
{
$this->_value = $value;
}
Use the Laravel automatic class resolution to provide parameters for your class dinamically:
function __construct (MyFooClass $foo)
{
$this->_foo = $foo;
}
And alter your ServiceProvider to provide no parameters to your class:
$this->app['myclass'] = $this->app->share(function()
{
return new MyClass();
});
Laravel will instantiante MyFooClass automatically for you, if it can locate it in the available source code of your application or if it's bound to the IoC container.
Note that all this assumes that you're not just passing a string in your constructor, the automatic resolution of the IoC container assumes your class has other class dependencies and inject those dependencies automatically (Dependency Injection).
If you really need to just pass strings or single values to constructors of classes that just do some calculations, you don't really need to create Facades for them, you can just:
$x = (new myClass("SimpleString"))->echoThat();
using a simple setter:
$x = new myClass();
$x->setValue("SimpleString");
$x->echoThat();
or, as you were already doing, which is acceptable:
$x = new myClass("SimpleString");
$x->echoThat();
And you can also use the IoC container to instantiate that class for you inside your other classes:
<?php
class Post {
private $myClass;
public function __construct(MyClass $myClass)
{
$this->myClass = $myClass;
}
public function doWhateverAction($value)
{
$this->myClass->setValue($value);
// Do some stuff...
return $this->myClass->echoThat();
}
}
Laravel will automatically pass an instance of your class and you can use it the way you need:
$post = new Post;
echo $post->doWhateverAction("SimpleString");
I found some goode information about model classes in the Facede Lavarel FW in this page
http://laravel.com/docs/eloquent
I assume here is the main explanation about your ploblem, the way to create a enter in database...
// Create a new user in the database...
$user = User::create(array('name' => 'John'));
// Retrieve the user by the attributes, or create it if it doesn't exist...
$user = User::firstOrCreate(array('name' => 'John'));
// Retrieve the user by the attributes, or instantiate a new instance...
$user = User::firstOrNew(array('name' => 'John'));
And here the way to create a simple new instance and initialize its variables:
$user = new User;
$user->name = 'John';
$user->save();
Based on that I assume there isnĀ“t a clear way to use a constructor in Lavarel.
i have to test class add_Hook
class add_Hook extends Hooks_base
i tried to create a mock of hooks_base like this:
> $this->oHookBaseMock = $this->getMock(
> 'Hooks_base',
> array('get_database','get_arguments'),
> array(null,'null') //this are the parameters for the constructor
> );
$this->hook->expects($this->any())
->method('get_database')
->will( $this->returnValue(true)
);
$this->hook->expects($this->any())
->method('get_arguments')
->will( $this->returnValue($arraySImpleXmlObject)
);
and doing something like this :
$hook = new add_Hook($this->hook)
And now my problem is that when i run the test it steels ask me for the 2 parameters of the parent class (hooks_base)
the constructor is something like this
public function __construct($parameter_1, $parameter_2) {
$this->_param1 = $parameter_1;
$this->_param2 = $parameter_2;
}
i dont' know how to disable the constructor of the parent class and if i do it.
I simply create an instance of the abstract class in my test. $Object = new ABSTRACT_CLASS() and have no code in the definition of the methods that need defined as I do not intend to test the abstract method.
class TestAbstractInput extends AbstractInput
{
public ImplementAbstractFunction()
{ // Purposely empty so nothing happens. This would be defined in normal class extending AbstractInput
}
...
}
class AbstractInputTest extends TestCase
{
// ...
public function setUp()
{
$this->TestClassObject = new TestAbstractInput();
}
public function test_isValid()
{
$this->assertEquals(1, $this->TestClassObject->isValid);
}
}
This way the individual methods may be tested. Then I test the normal class that usually extends the abstract class to test the functions that were implemented in that class.
class InputTest extends TestCase
{
// ...
public function setUp()
{
$this->TestClassObject = new AbstractInput();
}
// Parent function should still work
public function test_isValid()
{
$this->assertEquals(1, $this->TestClassObject->isValid);
}
public function test_ImplementAbstractFunction()
{
$this->assertTrue($this->AbstractFunction());
...
}
}
EDIT There is also the built in getMockForAbstractClass() which may work directly for you if you are using a new enough version. You can also instruct Mocks to not run the constructor.
You can't "mock" the parent class of your class. You could create a mock of your class and replace the parent methods that you are wanting to replace.
$add_hook = $this->getMock('add_Hook',
//This will mock these methods only and leave the rest untouched provided the class is able to be loaded.
array('get_database','get_arguments'),
array(param1, param2));
$this->hook->expects($this->any())
->method('get_database')
->will( $this->returnValue(true)
);
$this->hook->expects($this->any())
->method('get_arguments')
->will( $this->returnValue($arraySImpleXmlObject)
);
Your attempt was to somehow inject the parent into class. The class is an instance of the parent so you can't "mock" it without mocking the class itself.
In my opinion, this is not a good practice. You are testing the implementation of your class rather than testing the behavior of your class. Your test should rather check what your method does rather than how it does it. What is that 'get_database' and 'get_arguments' do? Perhaps you should be passing an instance of 'Hooks_base' into your class rather than extending it.
From what you have posted my test would look like:
public function testInit() {
$param1 = <what ever the argument needs to be>;
$param2 = <something else>;
$addHook = new add_Hook($param1, $param2);
$this->assertInstanceOf('Hooks_base', $addHook); //I would probably have this in a constructor test
$addHook->init();
//Assertions for what init() does
}
I intend to create a clone of an object's parent within the constructor of that parent. In short:
class ParentClass {
protected $property;
public function __construct() {
$this->property = clone $this;
}
}
class ChildClass extends ParentClass {
}
This works all fine, yet the problem with this code is the protected property getting populated with an instance of the ChildClass, in case the ChildClass is instantiated. I would however like it to be an instance of the ParentClass regardless of the class $this refers to.
I could of course combine debug_backtrace and new self() (in order to avoid endless recursion of constructor invocations) and assign the resulting ParentClass instance to the property, though such a soluation is verbose, as debug backtrace only returns string names of caller classes and methods.
Lastly, I could combine new self() and the provision of an argument to the instantiation of the object indicating if a "new self" should be created, but I dislike the solution because of its ugliness and redundancy.
Is there a way in PHP to find a "clone of self"?
As discussed in the comments, I think the reason this pattern is not working for you is that you have a poorly designed object hierarchy. In the example, ChildClass is a "type of" ParentClass, but also internally references a copy of ParentClass to do some delegated work.
From the comments, what you have must look something like this:
class BasicLogger {
protected $delegated_logger;
public function __construct() {
// initialise $this->delegated_logger somehow
}
public function logMessage($message, $flags) {
{
$prepared_message = $this->prepareMessage($message, $flags);
$this->deliverMessage($prepared_message);
}
private function prepareMessage($message, $flags) {
// implementation here
}
protected function deliverMessage($prepared_message) {
// implementation here
}
}
class MailLogger extends BasicLogger {
protected function deliverMessage($prepared_message) {
// different implementation here
if ( $mail_sending_failed ) {
$this->delegated_logger->logMessage('Oops, MailLogger failed...');
}
}
}
However, BasicLogger is actually performing multiple roles in the object hierarchy:
defining the interface that all loggers should adhere to (here represented as a single logMessage method)
providing a shared implementation of prepareMessage that all loggers will use, and an implementation of logMessage that depends on it plus a deliverMessage function
providing a specific implementation of deliverMessage that will be completely over-written by child classes
providing a mechanism for complex implementations to delegate to simpler implementations, without a way of distinguishing between the two
The first three roles should be separated into an interface, an abstract base class, and a simple implementation:
interface Logger {
public function logMessage($message, $flags = null);
}
abstract class BaseLogger implements Logger {
public function logMessage($message, $flags = null) {
{
$prepared_message = $this->prepareMessage($message, $flags);
$this->deliverMessage($prepared_message);
}
private function prepareMessage($message, $flags) {
// implementation here
}
abstract protected function deliverMessage($prepared_message);
}
class BasicTextLogger extends BaseLogger {
protected function deliverMessage($prepared_message) {
// implementation here
}
}
You can then use instances of BasicTextLogger wherever you need, including in other implementations of BaseLogger.
You might want to put the logic of having a delegated logger (the 4th role of my BasicLogger above) into another class for reuse. BasicTextLogger shouldn't inherit this behaviour, or you'll end up needing to provide a logger to a logger to a logger to a logger, ad infinitum.
abstract class ComplexLogger extends BaseLogger {
protected $delegated_logger;
public function __construct( Logger $delegated_logger ) {
if ( $delegated_logger instanceOf ComplexLogger ) {
throw new Exception('Attempted to delegate one complex logger to another; danger of recursion, so disallowed.');
} else {
$this->delegated_logger = $delegated_logger;
}
}
}
class MailLogger extends ComplexLogger {
protected function deliverMessage($prepared_message) {
// different implementation here
if ( $mail_sending_failed ) {
$this->delegated_logger->logMessage('Oops, MailLogger failed...');
}
}
}
This then allows you to perform Dependency Injection to provide your complex logger with a simple logger to delegate to:
$my_logger = new MailLogger( new BasicTextLogger() );
$my_logger->logMessage('Hello World!');
This may seem like a lot of different classes and interfaces, but each now has a clear responsibility. You could put the whole $delegated_logger logic into MailLogger, but you'd have to copy and paste it if you had another complex logger later. You might also be able to ignore the Logger interface, and just type-hint for classes deriving from the BaseLogger class, but it's possible you'll want an implementation that doesn't use prepareMessage at all - for instance, a DoNothingLogger.
I'm building a CMS using Laravel 4 and I have a base admin controller for the admin pages that looks something like this:
class AdminController extends BaseController {
public function __construct(UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
{
$this->auth = $auth;
$this->user = $this->auth->adminLoggedIn();
$this->message = $message;
$this->module = $module;
}
}
Im using Laravel's IOC container to inject the class dependencies into the constructor. I then have various controller classes that control the different modules that make up the CMS and each class extends the admin class. For example:
class UsersController extends AdminController {
public function home()
{
if (!$this->user)
{
return Redirect::route('admin.login');
}
$messages = $this->message->getMessages();
return View::make('users::home', compact('messages'));
}
}
Now this works perfectly however my problem, which is less of a problem and more of a efficiency issue, occurs when I add a constructor to the UsersController class. For example:
class UsersController extends AdminController {
public function __construct(UsersManager $user)
{
$this->users = $users;
}
public function home()
{
if (!$this->user)
{
return Redirect::route('admin.login');
}
$messages = $this->message->getMessages();
return View::make('users::home', compact('messages'));
}
}
Since the child class now has a constructor it means the parent's constructor isn't getting called and thus things the child class is dependant on, such as this->user are no longer valid, causing errors. I can call the admin controller's construct function via parent::__construct() however since I need to pass it the class dependencies I need to set these dependencies in the child constructor resulting in something that looks like this:
class UsersController extends AdminController {
public function __construct(UsersManager $user, UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
{
parent::__construct($auth, $messages, $module);
$this->users = $users;
}
// Same as before
}
Now this works fine in terms of its functionality; however it doesn't seem very efficient to me to have to include the parent's dependencies in every child class that has a constructor. It also looks quite messy. Does Laravel provide a way around this, or does PHP support a way of calling both the parent and child constructor without having to call parent::__construct() from the child?
I know this is a long question for what is effectively not a problem but more me just be ocd about efficiency, but I appreciate any ideas and/or solutions.
Thanks in advance!
There isn't a perfect solution and it's important to understand that this isn't an issue with Laravel itself.
To manage this, you can do one of three things:
Pass the necessary dependencies to the parent (which was your issue)
// Parent
public function __construct(UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
{
$this->auth = $auth;
$this->user = $this->auth->adminLoggedIn();
$this->message = $message;
$this->module = $module;
}
// Child
public function __construct(UsersManager $user, UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
{
$this->users = $users;
parent::__construct($auth, $message, $module);
}
Auto resolve the dependencies in the parent construct as stated by #piotr_cz in his answer
Create the instances in the parent construct instead of passing them as parameters (so you don't use Dependency Injection):
// Parent
public function __construct()
{
$this->auth = App::make('UserAuthInterface');
$this->user = $this->auth->adminLoggedIn();
$this->message = App::make('MessagesInterface');
$this->module = App::make('ModuleManagerInterface');
}
// Child
public function __construct(UsersManager $user)
{
$this->users = $users;
parent::__construct();
}
If you want to test your classes, the third solution will be more difficult to test. I'm unsure if you can mock the classes using the second solution, but you mock them using the first solution.
I know this is a super old question, but I just finished grinding on a similar question on my current project and came to an understanding with the issue at hand.
The basic underlying question here is:
If I'm extending a parent class that has a constructor. That constructor has injected dependancies and all of it's dependencies are already documented in the parent itself. Why do I have to include the parent's dependencies again in my child class?
I ran into this same issue.
My parent class requires 3 different dependencies. They're injected via the constructor:
<?php namespace CodeShare\Parser;
use CodeShare\Node\NodeRepositoryInterface as Node;
use CodeShare\Template\TemplateRepositoryInterface as Template;
use CodeShare\Placeholder\PlaceholderRepositoryInterface as Placeholder;
abstract class BaseParser {
protected $node;
protected $template;
protected $placeholder;
public function __construct(Node $node, Template $template, Placeholder $placeholder){
$this->node = $node;
$this->template = $template;
$this->placeholder = $placeholder;
}
The class is an abstract class so I can never instantiate it on it's own. When I extend the class, I still need to include all of those dependencies and their use references in the child's constructor:
<?php namespace CodeShare\Parser;
// Using these so that I can pass them into the parent constructor
use CodeShare\Node\NodeRepositoryInterface as Node;
use CodeShare\Template\TemplateRepositoryInterface as Template;
use CodeShare\Placeholder\PlaceholderRepositoryInterface as Placeholder;
use CodeShare\Parser\BaseParser;
// child class dependencies
use CodeShare\Parser\PlaceholderExtractionService as Extractor;
use CodeShare\Parser\TemplateFillerService as TemplateFiller;
class ParserService extends BaseParser implements ParserServiceInterface {
protected $extractor;
protected $templateFiller;
public function __construct(Node $node, Template $template, Placeholder $placeholder, Extractor $extractor, TemplateFiller $templateFiller){
$this->extractor = $extractor;
$this->templateFiller = $templateFiller;
parent::__construct($node, $template, $placeholder);
}
Including the use statements for the 3 parent dependencies in each class seemed like duplicate code since they're already defined in the parent constructor. My thought was to remove the parent use statements as they'll always need to be defined in the child class that extends the parent.
What I realized is that including the use for the dependencies in the parent class and including the class names in the parent's constructor are ONLY needed for type hinting in the parent.
If you remove the use statements from the parent and the type hinted class name from the parents constructor, you get:
<?php namespace CodeShare\Parser;
// use statements removed
abstract class BaseParser {
protected $node;
protected $template;
protected $placeholder;
// type hinting removed for the node, template, and placeholder classes
public function __construct($node, $template, $placeholder){
$this->node = $node;
$this->template = $template;
$this->placeholder = $placeholder;
}
Without the use statements and type hinting from the parent, it can no longer guarantee the type of class being passed to it's constructor because it has no way of knowing. You could construct from your child class with anything and the parent would accept it.
It does seem like double entry of code, but really in your paren't you're not constructing with the dependencies laid out in the parent, you're verifying that the child is sending in the correct types.
There's a way.
When BaseController autoresolves it's dependecies.
use Illuminate\Routing\Controller;
use Illuminate\Foundation\Application;
// Dependencies
use Illuminate\Auth\AuthManager;
use Prologue\Alerts\AlertsMessageBag;
class BaseController extends Controller {
protected $authManager;
protected $alerts;
public function __construct(
// Required for resolving
Application $app,
// Dependencies
AuthManager $authManager = null,
AlertsMessageBag $alerts = null
)
{
static $dependencies;
// Get parameters
if ($dependencies === null)
{
$reflector = new \ReflectionClass(__CLASS__);
$constructor = $reflector->getConstructor()
$dependencies = $constructor->getParameters();
}
foreach ($dependencies as $dependency)
{
// Process only omitted optional parameters
if (${$dependency->name} === null)
{
// Assign variable
${$dependency->name} = $app->make($dependency->getClass()->name);
}
}
$this->authManager = $authManager;
$this->alerts = $alerts;
// Test it
dd($authManager);
}
}
So in child controller you pass only Application instance:
class MyController extends BaseController {
public function __construct(
// Class dependencies resolved in BaseController
//..
// Application
Application $app
)
{
// Logic here
//..
// Invoke parent
parent::__construct($app);
}
}
Of course, we could use Facade for application
You must pass the dependencies to the parent constructor to have them available in the child. There is no way to inject the dependencies on the parent construct when you instantiate it via the child.
I came across the same issue, when extending my base Controller.
I opted for a different approach than the other solutions shown here. Rather than rely on dependency injection, I'm using app()->make() in the parents constructor.
class Controller
{
public function __construct()
{
$images = app()->make(Images::class);
}
}
There may be downsides to this simpler approach - possibly making the code less testable.
I've also ended up with this problem and cleared this mess by not calling constructor at child class and use extra needed dependencies inside the function parameters.
It will work with controllers because you won't need to call these functions manually and you can inject everything there. So common dependencies goes to the parent and less needed will be added to the methods itself.