Nette 3.0 nahrazení za loadDefinition
- Barbarossa
- Člen | 74
Ahoj,
existuje už někde návod jak migrovat na Nette DI 3.0? Nejsem v tom
zběhlý, a tak s tím docela bojuju. Dneska to je loadDefinition, které je
v 3.0 označené jako deprecated s pomocnou
hláškou: loadDefinition() is deprecated.
mám tento kus kódu, který bych rád převedl, asi do loadDefinitions, ale nevím jak…
// převzato z contributte/flysystem
$processor = $builder->addDefinition($adapterName)
->setAutowired(false);
Compiler::loadDefinition($processor, $args['adapter']); //$args['adapter'] je Statement (DI)
Díky za pomoc.
- David Grudl
- Nette Core | 8227
Návod, jak migrovat, zatím není, protože ještě nevyšla ostrá verze a některé věci se mohou měnit.
Co přesně potřebuješ zmigrovat?
- Barbarossa
- Člen | 74
Aha díky, nevšiml jsem si že DI je beta (zatímco většina je RC). Zkouším balíky z Contributte (na Nette 3) a už je mi jasné proč se nikdo nehrne do aktualizování repozitářů…
Můj názor je takový, že nikdo jiný zřejmě to DI lépe nenapíše, a pokud jsi přesvědčený, že to máš napsané dobře a má to budoucnost tak se hold vývojáři rozšíření musí přizpůsobit… nebo nevím kolik návrhů na zlepšení denně od nich dostáváš.
Mě by zatím zajímal ten přepis toho výše uvedeného kódu, je to nějak
takhle?
Celý 2.4 kod je zde
$processor = $builder->addDefinition($adapterName)
->setAutowired(false);
$this->compiler->loadDefinitions([$args['adapter']], $adapterName);
Editoval Barbarossa (3. 2. 2019 15:39)
- David Grudl
- Nette Core | 8227
Statické metody Compiler::loadDefinition()
a
loadDefinitions()
nahradily nestatické
Compiler::loadDefinitionsFromConfig(array $config)
a
CompilerExtension::loadDefinitionsFromConfig(array $config)
, kde
$config
je pole definic služeb (vlastně obsah sekce
services:
).
Rozdíl mezi metodou ze třídy Compiler a CompilerExtensions je ten, že ta v CompilerExtension prefixuje názvy tříd názvem extension.
Takže v uvedeném kódu contributte/flysystem by se použilo
$this->compiler->loadDefinitionsFromConfig([$adapterName => $args['adapter']]);
Je tam $this->compiler, protože $adapterName už je prefixovaný.
edit: loadDefinitionsFromConfig
- Croc
- Člen | 270
Zdravím, mám obdobný problém. Mám aplikaci, která se částečně skládá z interních extensions.
Aktuálně mám DI takto:
private $defaults = [
];
/**
*
*/
public function loadConfiguration() {
$this->validateConfig($this->defaults);
$config = $this->loadFromFile(__DIR__ . '/neco.neon');
$config = Nette\DI\Helpers::expand($config, $this->validateConfig($this->config));
Nette\DI\Compiler::loadDefinitions(
$this->getContainerBuilder(),
$config['services'],
$this->name
);
}
Koukal jsem do dokumentace, ale vůbec netuším jak to přepsat aby to jelo na Nette 3.
Moc děkuju
- Marek Bartoš
- Nette Blogger | 1274
@Croc Však už to David napsal –
$this->compiler->loadDefinitionsFromConfig($config['services'])
- Croc
- Člen | 270
Díky za odpověď. Spíš se mi jedná o config a parametry:
hlavní /app/config/config.neon:
agenda:
agendaFilesDir: 'agenda_files'
extension config /libs/agenda/src/di/agenda.neon:
services:
- Agenda\Model\FileModel(%agendaFilesDir%)
/**
* @return Nette\Schema\Schema
*/
public function getConfigSchema(): Nette\Schema\Schema
{
return Expect::structure([
'migration' => Expect::array()->dynamic(),
'iv' => Expect::string('xxxxxxx')->dynamic(),
])->castTo('array');
}
public function loadConfiguration()
{
$config = $this->loadFromFile(__DIR__ . '/agenda.neon');
$this->compiler->loadDefinitionsFromConfig($config['services']);
// půvondí část pro nette 2.4
// $this->config - pole defaultních parametrů (nyní přepsáno do getConfigSchema)
// $config = $this->loadFromFile(__DIR__ . '/agenda.neon');
// $config = Nette\DI\Helpers::expand($config, $this->validateConfig($this->config));
// Nette\DI\Compiler::loadDefinitions(
// $this->getContainerBuilder(),
// $config['services'],
// $this->name
// );
}
Ve službě v extension agenda potřebuju parametr z hlavního configu.
Moc děkuju za pomoc
Editoval Croc (6. 6. 2019 13:05)
- Croc
- Člen | 270
Děkuji za odpověd.
Takto to právě nechci, aby se to ztratilo v ostatních parametrech, které s extension nesouvisí (takto jsem to měl na začátku).
Když konfiguruješ jakoukoliv extension, tak to je taky tak, název extension a pak parametry.
Koukal jsem do kódu nějakých extension pro Nette 3, ale mám v tom dost hokej a netuším jak to napsat. V dokumentaci také nic…
- MajklNajt
- Člen | 498
v tom prípade to v config.neon urob tak, ako si písal:
agenda:
agendaFilesDir: 'agenda_files'
a vytiahni si ho cez:
public function getConfigSchema(): Nette\Schema\Schema
{
return Expect::structure([
'agendaFilesDir' => Expect::string(),
'migration' => Expect::array()->dynamic(),
'iv' => Expect::string('xxxxxxx')->dynamic()
])->castTo('array');
}
- Croc
- Člen | 270
To bohužel vůbec nepomohlo. Stále stejná chyba:
Nette\InvalidArgumentException
Missing parameter 'agendaFilesDir'.
EDIT: Zdá se že toto funguje (nicméně validateConfig
je
deprecated):
/**
*
*/
public function loadConfiguration() {
$config = $this->loadFromFile(__DIR__ . '/agenda.neon');
$config = Helpers::expand($config, $this->validateConfig($this->config));
$this->compiler->loadDefinitionsFromConfig($config['services']);
}
Editoval Croc (6. 6. 2019 16:40)
- MajklNajt
- Člen | 498
sorry, až teraz som si všimol, že ty sa snažíš ten parameter dostať do servisy, takže máš 2 možnosti:
- zaregistrovať servisu do kontajneru ručne v
CompilerExtension
, kde jej ten parameter predáš z cez$this->config->agendaFilesDir
2) malo byť fungovať dať pred názov parametru prefix
extension
, ktorý sa nahradí kľúčom, pod ktorým registruješ
rozšírenie:
services:
- Agenda\Model\FileModel(extension.agendaFilesDir)
EDIT: tak to druhé riešenie funguje iba so
službami – @extension.serviceName
Editoval MajklNajt (6. 6. 2019 20:11)
- Croc
- Člen | 270
Díky moc za nasměrování, nakonec se mi to asi povedlo:
/**
* Class AgendaExtension
* @package Agenda\DI
*/
class AgendaExtension extends CompilerExtension
{
/**
* @return Schema
*/
public function getConfigSchema(): Schema
{
return Expect::structure([
'agendaFilesDir' => Expect::string()->dynamic(),
])->castTo('array');
}
/**
*
*/
public function loadConfiguration()
{
$config = $this->loadFromFile(__DIR__ . '/agenda.neon');
$this->compiler->loadDefinitionsFromConfig($config['services']);
$builder = $this->getContainerBuilder();
$builder->addDefinition(null)
->setFactory(
FileModel::class,
[
'agendaFilesDir' => $this->config['agendaFilesDir'],
]
);
}
}
Díky!!!
- Ivorius
- Nette Blogger | 119
@Mabar mi doporučil ještě jedno možné řešení – trošku jsem si to poupravil, ale třeba se to bude hodit i někomu dalšímu.
public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
$realParameters = $builder->parameters;
$builder->parameters = Arrays::mergeTree((array) $this->config, $realParameters);
$extensionNeon = $this->loadFromFile('./something.neon');
$services = $extensionNeon['services'];
$this->loadDefinitionsFromConfig($services);
$builder->parameters = $realParameters;
}