Dependency-injection in real life

后端 未结 3 1283
温柔的废话
温柔的废话 2021-01-31 19:10

I am building a really minimal MVC framework to increase my PHP knowledge and challenge myself. I\'ve come to the point where Classes begin to be dependent on each other to work

3条回答
  •  再見小時候
    2021-01-31 19:54

    I don't know much about the specific lib, but assuming it lets you use a factory, let the factory return the same instance.

    Edit: Ok, this is simply on the Bucket GitHub index page.

    class MyFactory {
      function new_PDO($container) {
        return new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
      }
    }
    
    $bucket = new bucket_Container(new MyFactory());
    $db = $bucket->get('pdo');
    

    So in your case you could simply do:

    class MyFactory {
       private $pdo;
       function new_Database($container) {
         if($this->pdo){
             return $this->pdo;
         }
         return $this->pdo = new PDO("mysql:host=localhost;dbname=addressbook", "root", "secret");
       }
    }
    $factory = new MyFactory();
    
    $session_container = new bucket_Container($factory);
    $session_container->create('Database_Sessions');
    
    $log_container = new bucket_Container($factory);
    $log_container->create('Database_Log');
    

    Something like that. Doesn't seem like rocket science.

    Edit2: I don't have enough rep points to comment on the question (bit silly), but in response to your "modularity" concern: think of the container as the "glue" of your application. Indeed, if you have a large application, you may want to "glue" inside an isolated part of your application only. That is a valid encapsulation concern. But even then you still need a container that handles injection at the highest level of abstraction. If you just create a separate container for every part of your application, you either end up with unneeded duplication of instances, or you have to apply another level of instance management, which doesn't improve the encapsulation in any way: you're still sharing instances between different parts of your application.

    My advice would be to use a single container at the bootstrap level. If you want added encapsulation for specific parts of your application (modules, plugins, whatever), use "child containers". A child container inherits the instances from the parent container, but the parent container knows nothing of the child (as far as he's concerned, he's still a bachelor ;)). Could be that Bucket supports this by default, I know other DI containers do. If not, it's really easy to implement using a Decorator. Imagine something like this:

    class MyContainerType extends bucket_Container {
    
        private $_parent;
        private $_subject;
    
        public function  __construct($factory = null, bucket_Container $parent = null){
            $this->_parent = $parent;
            $this->_subject = new bucket_Container($factory);
        }
    
        public function get($key){
            $value = $this->_subject->get($key);
            if($value){
                return $value;
            }
            return $this->_parent->get($key);
        }
        /**
         * Override and delegation of all other methods
         */
    }
    

提交回复
热议问题