propelorm/Propel2 — Issue #51: [RFC] Making a true Runtime Singleton
Author: fzaninotto
Created: 2011-11-16 16:12:33+00:00
State: open
Labels: RFC, Runtime

The `Propel` class is not a true singleton. It's a class full of static methods, not easily replaceable. I suggest to refactor it to a true [singleton class](http://en.wikipedia.org/wiki/Singleton_pattern), the only one in `Runtime`, holding a reference to all the necessary configuration:

* connections
* runtime model (Map classes)
* adapters
* logger

I have started refactoring the `Propel` class to make the domain more apparent (see https://github.com/fzaninotto/Propel2/commit/2f1cbfb84d2264796aa5ade67c765156c11a61e0). This must go further.

So in the runtime code, any call to

```
$con = Propel::getConnection(BookPeer::DATABASE_NAME, Propel::CONNECTION_READ);
```

should be rewritten to something like:

```
$con = Propel::getInstance()->getSlaveConnection(BookPeer::DATABASE_NAME);
```

The naming is important. `Propel`might not be the best name. `Registry` also sounds too vague for me. It's a registry for runtime configuration - there are other types of registry in Propel. `Manager` is not good either, as it doesn't manage much more than configuration. Any suggestion? I'd vote for `Propel\Runtime\Configuration`:

```
$con = Configuration::getInstance()->getSlaveConnection(BookPeer::DATABASE_NAME);
```

which, incidentally, is a little shorter than the `Propel::getConnection()` version.

But there is also a `Configuration` namespace in Runtime. However, it contains code that can be removed if the `convert-conf` class creates a `Configuration` singleton. Something like:

```php
addDatasource('bookstore', array(
'dsn' => 'mysql:dbname=test',
'user' => 'foo',
'password' => 'bar',
'options' => array('ATTR_PERSISTENT' => false)
));
$conf->addAdapter('bookstore', 'Propel\Runtime\Adapter\MysqlAdapter');
$conf->setDefaultDatasource('bookstore');
```

Advantage: Configuration can easily be done by hand, using this class. The `convert-conf` task would just be a utility, taking XML as input but also YAML, or whatever you want. And in the Symfony2 integration, no need for that - the DI would populate the conf at will, maybe by subclassing it and injecting the DIC. That means we can probably get rid of the classes currently under `Propel\Runtime\Configuration`.

I know it's a BC break, but I think it's necessary.

Comments?