Injectovanie repozitarov do komponent

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
tolljump
Člen | 47
+
0
-

Zdravim vas.
Mal by som relativne jednoduchu otazku, no ja s partakmi si s tym nevieme pomoct, rsp. neviem co je ten „best-practice“.

V presentroch bezne pouzivame repositare s ktorymi robime dotazy do databazy. Cize napr.:

/** @var \App\Model\System\SiteSettingsRepository @inject **/
	public $siteSettingsRepository;

Vsetky repozitare su definovane ako sluzby v configu:

services:
	- App\Model\SettingsModel

Teraz moja otazka…
Mame komponenty ktore dedia od UI\Control a pomocou createComponentNAME() si ich v presentri vytvarame. Potrebujeme do tychto komponent predavat niekolko repozitarov, pripadne identitu usera a pod.
Najjednoduchsie riesenie ktore poznam je predavat ich pomocou constructora, no pride mi to ako trochu „nepekne“ riesenie. Najradsej by som bol ak by sa dali injectovat priamo v komponente (tak ako v presentri) presne podla potreby kazdej komponenty. Tiez aj napr. identita usera by sa mohla uz nejak „nachadzat“ priamo v komponente aby som ju nemusel predavat cez constructor.
Teraz nam vznika nieco taketo:

protected function createComponentRandomProducts() {
		$user = $this->user;
		$componentsSettings = $this->componentsSettings['randomProducts'];
		$sliderProducts = new App\Components\RandomProductsControl($componentsSettings, $this->shopProductRepository, $this->settingsRepository, $this->settings, $user);
		$sliderProducts->invalidateControl();
		return $sliderProducts;
	}

Ako sa zbavit toho predavania si repozitarov, identity usera, pripadne inych premennych ale mat ich vsetky ktore potrebujem uz priamo v komponente?

Dakujem velmi pekne za vsetky rady

David Kudera
Člen | 455
+
0
-

Řekl bych, že určitě bude nejlepší používat komponenty společně s generovanými továrničkami

Edit: a s tím zůstat u konstruktorů ;-)

Editoval David Kudera (29. 8. 2014 17:24)

tolljump
Člen | 47
+
0
-

Dakujem za rychlu reakciu David.

Ten clanok o autowiringu som uz cital, no nejak som si nevedel komplexne predstavit jeho zapracovanie do mojich aktualnych komponent. Hlavne ten „best-practice“ kde vsetky tie subory ukladat, ako to „najkrajsie“ vsetko definovat v config.neon a pod.

Musim si to nejak ujasnit… Potrebujem pouzit aj RegistrationControlFactory aj IRegistrationControlFactory? Ako mam chapat tieto 2 triedy? Obidve ich potrebujem registrovat do configu?
Kde by bolo idealne ich v ramci standardnej struktury aplikacie umiestnit? Priamo ku komponente napriklad (/App/Components/RandomProducts/IRegistrationControlFactory.php) ?

Potom budem komponentu v presentri vyvolavat uz len nejak takto? :

private $randomProductsControlFactory;

public function injectRegistrationControlFactory(RandomProductsControlFactory $factory)
{
    $this->randomProductsControlFactory = $factory;
}

protected function createComponentRandomProducts()
{
    return $this->randomProductsControlFactory->create();
}

a vytvorim si triedu RandomProductsControlFactory v ktorej bude cely ten constructor? Naco potom dalej sluzi este ten

interface IRegistrationControlFactory
{
    /** @return RegistrationControl */
    function create();
}

??

David Kudera
Člen | 455
+
0
-

Takže… :-)

Ano, budeš mít 2 třídy. Můžeš je dávat vedle sebe i pojmenované, jako jsi tu napsal. Třeba já mám ve složce app složku Components a v ní třeba User/SignUpForm, no a uvnitř mám klasický SignUpForm a ISignUpFormFactory.

Do configu potom stačí v ideálním případě registrovat jen továrničku:

services:

	-
		implement: App\Components\User\SignUpForm\ISignUpFormFactory

to bude fungovat ale jen pokud máš správně napsanou továrničku s metodou create a platnou anotací @return.

ten kód v presenteru máš správně (osobně dávám přednost konstruktorům i v presenteru, ale to je jen na tobě).

konstruktor samotné třídy si necháš takový, jaký je teď

ještě koukni sem , to jsem nedávno psal jeden menší příklad, tam jde vidět, jak si takovou komponentu registrovat i s předáváním dalších parametrů přes konstruktor. Což jak tak koukám, tak by možná v tvém kódu mohla být proměnná $componentsSettings

Editoval David Kudera (29. 8. 2014 18:13)

Šaman
Člen | 2668
+
0
-

Jen bych dodal, že stačí do configu uvést:

services:
	- App\Components\User\SignUpForm\ISignUpFormFactory

A v presenteru

<?php
private $signUpFormFactory;

public function injectSignUpFormFactory(App\Components\User\SignUpForm\ISignUpFormFactory $factory)
{
    $this->signUpFormFactory= $factory;
}
?>

Editoval Šaman (31. 8. 2014 19:30)