F
F
frolover2016-07-22 11:30:24
PHP
frolover, 2016-07-22 11:30:24

Dependency management class, how do you like the implementation?

Outlined the dependency management class in the application

/**
 * Class DependencyManager
 */
class DependencyManager {

    /**
     * @var array of dependencies
     */
    public $dependencies;

    /**
     * DependencyManager constructor
     */
    public function __construct() {

        $this->dependencies = [

          [
              'class' => 'SomeClass',
              'dependencies' => [
                  'DependentedClass', 'SecondDependentedClass'
              ]
          ]

        ];

    }

    /**
     * @param $class
     * @return null OR Dependencies of class
     */
    public function checkDependencies($class) {

        $dependenciesByClass = null;

        foreach( $this->dependencies as $data ) {

            if($data['class'] === $class) {

                $dependenciesByClass = $data['dependencies'];
                break;
            }

        }

        return $dependenciesByClass;

    }

}

/**
 * Class DependentedClass
 */
class DependentedClass {

    public $variable = 'this text placed in DependentedClass <br />';

}

/**
 * Class SecondDependentedClass
 */
class SecondDependentedClass {

    public $moreVariable = 'this text placed in SecondDependentedClass';

}

/**
 * Class SomeClass
 * class for example
 * It is dependent on other classes
 */
class SomeClass {

    public $varInDependentedClass;
    public $varInSecondDependentedClass;


    public function __construct(DependentedClass $dependentedClass, SecondDependentedClass $secondDependentedClass) {

        $this->varInDependentedClass = $dependentedClass->variable;

        $this->varInSecondDependentedClass = $secondDependentedClass->moreVariable;

    }

}

/**
 * Class Loader
 * This class creates an instance of any class
 */
class Loader {

    public $className; 

    public $dependencyManager;

    /**
     * Loader constructor.
     * @param DependencyManager $dependencyManager
     */
    public function __construct(DependencyManager $dependencyManager) {

        $this->dependencyManager = $dependencyManager;

    }

    /**
     * @return null|object
     * this method loads classes
     */
    public function loadClass() {

        $dependencies = null;
        $arrayObjects = null;
        $reflection = null;
        $instance = null;

        $this->className = 'SomeClass';

        if( !is_null($this->className) ) {

            $dependencies = $this->dependencyManager->checkDependencies($this->className);

            if( !is_null($dependencies) ) {

                for($i = 0; $i < count($dependencies); $i++) {

                    $arrayObjects[$i] = new $dependencies[$i];

                }

                $reflection = new ReflectionClass( $this->className );

                $instance = $reflection->newInstanceArgs($arrayObjects);

            } else {
                $instance = new $this->className;
            }
        }
        return $instance;
    }
}

Usage:
$loader = new Loader( new DependencyManager() );

var_dump( $loader->loadClass() );

/*
 * var_dump() results:
 * object(SomeClass)#6
 *  (2) {
 *  ["varInDependentedClass"] => string(43) "this text placed in DependentedClass"
 *  ["varInSecondDependentedClass"] => string(42) "this text placed in SecondDependentedClass"
 *  }
 */

A very convenient thing, now you can test the application in parts.
BUT
What confuses me:
1. The fact that you need to manually collect an array of dependencies (DependencyManager::__construct() method);
2. That perhaps I missed something or piled up, for example, the formation of an array of dependency objects (Loader::loadClass() method)
UPDATE
Another idea came to passing interfaces, not objects, in classes with dependencies.
Please note that this is not a fully working option, and I ask for advice on the main idea of ​​\u200b\u200bthe class, and not on missed checks and so on. Many points are maximally facilitated for quick understanding.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
Grigory Esin, 2016-07-22
@frolover

Have you decided to write your own Dependency Injection Container with blackjack and ***?
Yes, to prescribe dependencies by hand (in the config) is the norm.
If you do not want to do this, then google for the keywords "di container autowiring"

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question