2

I'm trying to figure out the best practices for dependency injection in PHP.

Question: Do I have to inject all dependencies of a subclass into the parent class? I use the terms 'parent' and 'child' in terms of a composition relationship.

My hesitation is because I find myself giving the parent class all kinds of dependencies so that it can just pass them down to dependent child classes.

Edit:

Below is a more concrete example of what I'm talking about. MyClassA does not need the database connection object or the logger. DoSomething does need these objects, however. What is the best way to get the database connection and logger to the DoSomething instance? I don't want to use singleton objects or global objects for the sake of unit testing. Also, this example only uses to classes. What if there are 3 or 4 and the 3rd or 4th needs some object instance but the first 2 or 3 don't? Does MyClassA just pass the object to the next, and so on?

class MyClassA {
  protected $_doSomethingObject;

  public function doSomething()
  {
    return $this->_doSomethingObject()->doSomethingElse();
  }

  public function setDoSomethingObject($doSomethingObject)
  {
    $this->_doSomethingObject = $doSomethingObject;
  }
}

class DoSomething {
  protected $_logger;
  protected $_db;

  public function doSomethingElse()
  {
     $this->_logger->info('Doing Something');
     $result = $this->_db->getSomeDataById();
     return $results;
  }

  public function setLogger($logger)
  {
     $this->_logger = $logger;
  }

  public function setDBConection($db)
  {
     $this->_db = $db;
  }
}

Is the best way the example I show below? If so, then the best way is to work backwards so to speak...?

    $logger = new Logger();
    $db = new DBConnection();    

    $doSomething = new DoSomething();
    $doSomething->setLogger($logger);
    $doSomething->setDBConnection($db);

    $a = new MyClassA();
    $a->setDoSomething($doSomething);
3
  • 2
    In most cases, aren't these child objects injected into the parents? If so you'd first be injecting their dependencies before injecting those objects into the parent. Do you have any simple concrete examples? Commented Nov 22, 2011 at 0:20
  • I added some pseudo code to look at. Thanks for the reply! Commented Nov 22, 2011 at 6:59
  • There is such a thing as Law of Demeter. Read about it. Commented Nov 22, 2011 at 9:13

2 Answers 2

1

If so, then the best way is to work backwards so to speak...?

Yes. As I mentioned in the comment, you set up the inner most objects first.

If an object create another object internally that isn't exposed, then it could pass along its injected objects if appropriate. For example:

class DoSomething {
// ...
  public function foo() {
    $foo = new Foo();
    $foo->setLogger($this->_logger);
    return $foo->bar();
  }
}

However, if that secret Foo object needed references to other things that DoSomething didn't have, then you've got design issues. If that happens you need to do whatever is appropriate:

  • Inject a foo object into the parent object prior to calling foo().
  • Inject that dependency into the parent object prior to calling foo().
  • Add the dependency as a function argument.
  • Refactor code into a better design that doesn't create that problem.
Sign up to request clarification or add additional context in comments.

Comments

0

You need only include the dependancies in the classes that are going to directly need them. Since the required/included files will be loaded whenever the base class loads, they will automatically be available to any child classes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.