Dependency injection when you do not control creation and use

How to do it?

I have a Model class that is the parent of many subclasses, and this model depends on the database connection and the caching mechanism.

Now, when it starts to bother: I cannot control how each object gets an instance or is used, but I have control over the methods that are used by subclasses.

Currently, I have resorted to using static methods and properties for dependency injection:

class Model
{
    private static $ database_adapter;
    private static $ cache_adapter;
    public static function setDatabaseAdapter (IDatabaseAdapter $ databaseAdapter)
    {
        self :: $ databaseAdapter = $ databaseAdapter;
    }
    public static function setCacheAdapter (ICacheAdapter $ cacheAdapter)
    {
        self :: $ cacheAdapter = $ cacheAdapter;
    }
}

What happened well, but it feels dirty (it creates a global state for all models).

I looked at the factory pattern, but removes control of the instance from subclasses (how to create an instance of an object with a variable number of parameters in it constructor?).

Now I'm at a loss. Any help would be appreciated.

+3
source share
2 answers

, . , , PHPUnit, , $testing. Singletons. , .

+1

, , . :

abstract class Model {
    protected $_database_adapter;
    protected $_default_database_adapter;

    public function getDatabaseAdapter() {
        if(!$this->_database_adapter) {
            if(self::$_default_database_adapter) {
                $this->_database_adapter = self::$_default_database_adapter;
            } else {
                throw new Exception("No adapter set yet");
            }
        }
        return $this->_database_adapter;
    }

    public function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
        $this->_database_adapter = $databaseAdapter;
    }

    public static function setDefaultDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
        self::$_default_database_adapter = $databaseAdapter;
    }
}

, / Registry, Container - .

, , . script :

Model::setDatabaseAdapter($default);
$my_model->query('....');
Model::setDatabaseAdapter($another_adapter);
$my_other_model->query('....');
Model::setDatabaseAdapter($default);

:

mysql_select_db('default_db');
mysql_query('...');
mysql_select_db('other_db');
mysql_query('...');
mysql_select_db('default_db');
0

Source: https://habr.com/ru/post/1732666/


All Articles