Nette 3.0 nahrazení za loadDefinition

před 12 měsíci

Barbarossa
Backer | 65
+
0
-

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.

před 12 měsíci

David Grudl
Nette Core | 6928
+
0
-

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?

před 12 měsíci

Barbarossa
Backer | 65
+
0
-

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)

před 12 měsíci

David Grudl
Nette Core | 6928
+
+1
-

Rozumím o co jde, najdu nějaký způsob, jak to řešit.

před 11 měsíci

David Grudl
Nette Core | 6928
+
+1
-

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

před 8 měsíci

Croc
Backer | 264
+
0
-

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

před 8 měsíci

Mabar
Člen | 201
+
+1
-

@Croc Však už to David napsal – $this->compiler->loadDefinitionsFromConfig($config['services'])

před 8 měsíci

Croc
Backer | 264
+
0
-

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)

před 8 měsíci

MajklNajt
Člen | 274
+
0
-

keď si upravíš v config.neon:

parameters:
    agendaFilesDir: 'agenda_files'

potom môžeš v použiť v agenda.neon:

services:
    - Agenda\Model\FileModel(%agendaFilesDir%)

před 8 měsíci

Croc
Backer | 264
+
0
-

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…

před 8 měsíci

MajklNajt
Člen | 274
+
0
-

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');
}

před 8 měsíci

Croc
Backer | 264
+
0
-

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)

před 8 měsíci

MajklNajt
Člen | 274
+
0
-

malo by to fungovať tak, ako som napísal – máš tú extension zaregistorvanú pod menom agenda?

před 8 měsíci

MajklNajt
Člen | 274
+
0
-

sorry, až teraz som si všimol, že ty sa snažíš ten parameter dostať do servisy, takže máš 2 možnosti:

  1. 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)

před 8 měsíci

Croc
Backer | 264
+
0
-

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!!!