Dynamická změna connection v aplikaci
- michal.lohnisky
- Člen | 64
Ahoj,
ve své aplikaci spouštím CRON script, který se ve foreachi připojuje k několika databázím (jejich názvy jsou v jiné databázi a jsou dynamicky přidávány). Při zpracování požadavku využívám svoje modely, z nichž má každý nastavené Nette\Database\Connection.
Je zde možnost přepsat connection všem modelům najednou? Tedy lze nějak nahradit ‚nette.database.default‘ v cyklu foreach?
- David Matějka
- Moderator | 6445
pridavat/odebirat sluzby za behu muzes metodami removeService a addService v Nette\DI\Container
vymena nette.database.default asi nebude problem, problem bude, ze jiz instancovane modely budou mit injectnutou stary pripojeni, ale melo by stacit pouzit removeService na ty modelovy sluzby a nechat je potom nette znovu vytvorit s novym spojenim
- michal.lohnisky
- Člen | 64
Tak tedy konkrétně (třeba se to bude někomu hodit):
$params = $this->context->parameters['database'];
$dsn = $params['driver'] . ":dbname=" . $dbname . ";host=" . $params['host'];
// reload connection
$this->context->removeService('nette.database.default');
$connection = new \Nette\Database\Connection($dsn, $params['user'], $params['password']);
$connection->setSelectionFactory(new \Nette\Database\SelectionFactory($connection, new \Nette\Database\Reflection\DiscoveredReflection($connection, $this->context->getService('cacheStorage')), $this->context->getService('cacheStorage')));
$this->context->addService('nette.database.default', $connection);
// reload ostatních služeb
foreach (array(
'model1',
'model2',
) as $serviceName
) {
$this->context->removeService($serviceName);
}
- thunderbuff
- Člen | 164
Dynamické nahrazování služby mi docela smrdí. Čistší by dle mého názoru bylo vytvářet novou instanci connection a dál si předávat přímo ji. Services by se měly předávat pomocí DI odshora dolů, cpát je za běhu aplikace „zpět nahoru“ je ošklivé.