Factory pro vice podobnych komponent

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

Ahoj mam v aplikaci dve podobne komponenty. Vlastne oboje delaji to same, akorat, kazda pouziva jiny model.

Priklad:

namespace App\Components;

class ControlTabsFactory {

	private static $types = array(
		'car' => array(
			'class' => 'CarTabs',
            'model' => 'App\Model\Cars'
		),
		'person' => array(
			'class' => 'PersonTabs',
            'model' => 'App\Model\Persons'
		),
	);

	public function create($type) {

		if (in_array($type, array_keys(self::$types))) {
			$class = self::$types[$type]['class'];
			$model = self::$types[$type]['model'];
			return new $class(new $model(/* pripojeni k databazi */));
		}
		throw new \Exception('Sorry bro! You are not my type. :D');
	}
}

Pripadam si, ze toho pisu zbytecne moc a, ze by to za me nette mohlo nejak vycarovat samo (autowiring).
Nejde to nejak z jednodusit, nebo jak tam pripadne dostat to pripojeni k db? Dekuji za rady.

Editoval marty666 (9. 9. 2014 12:51)

Šaman
Člen | 2666
+
0
-

Myslím, že by to šlo zjednodušit.

  1. vytvoř si rozhraní pro generované továrničky ICarTabsFactoryIPersonTabsFactory
  2. ty si injectni to té tvé továrny
  3. podle svoji logiky se rozhodni, kterou z nich použiješ

Editoval Šaman (9. 9. 2014 12:46)

marty666
Člen | 26
+
0
-

Tak jsem to zkousel podle tohoto navodu: https://doc.nette.org/…tion/factory

namespace App\Components;

class ControlTabsFactory {

	private $personTabsFactory;

	private $carTabsFactory;

    public function injectPersonTabsFactory(IPersonTabsFactory $factory)
    {
		$this->personTabsFactory = $factory;
	}

	public function injectCarTabsFactory(ICarTabsFactory $factory)
    {
		$this->carTabsFactory = $factory;
	}

    public function create($type) {

        switch ($type) {
            case 'person':
                return $this->personTabsFactory->create();
            case 'car':
                return $this->carTabsFactory->create();
            default:
                break;
        }
        throw new \Exception('Sorry bro! You are not my type. :D');
    }
}

presenter mam:

use App\Components\ControlTabsFactory;

class CarsPresenter extends BasePresenter
{
	private $controlTabsFactory;

	public function __construct(ControlTabsFactory $factory)
    {
		$this->$controltabsFactory = $factory;
    }

    protected function createComponentCarTabs()
    {
		return $this->$controlTabsFactory->create('car');
    }
}
--/

a jednotlive interface:
namespace App\Components;

inreface ICarTabsFactory
{
    /**
     *	@return CarTabs
     */
	public function create();
}

// to same pro person factory
--/

config:

services:
	- App\Components\ControlTabsFactory
	- App\Components\ICarTabsFactory
	- App\Components\IPersonTabsFactory

jenze pri kazdem pokusu o zavolani o metodu create() to hazi:

 Call to a member function create() on a non-object. To znamena, ze ty inject funkce se nezavolaly. Tak to vypada, ze to bunu muset nabusit rucne :D

Editoval marty666 (9. 9. 2014 16:37)

David Matějka
Moderator | 6445
+
+1
-
  1. inject metody se volaji defaultne pouze u presenteru, jinde je lepsi pouzit konstruktor
  2. v presenteru ti pred controlTabsFactory prebyva $
  3. kdyz v presenteru znas ten typ, nebude lepsi do nej injectovat rovnou ICarTabsFactory?
Šaman
Člen | 2666
+
+1
-

Starý návod – ve stabilní verzi Nette nikdy nešlo injectovat pomocí metod, nebo anotací nikam jinam, než do presenteru. To šlo jen v dev verzi Nette 2.1 (která měla tolik vychytávek oproti 2.0, že na ni mnoho lidí vyvíjelo, ač nebyla stable).
Injectuj konstruktorem.

David Kudera
Člen | 455
+
+1
-

Osobně mi přijde daleko lepší tento způsob komponent.

No a jinak použij ten „inject“ přes konstruktor jako máš v presenteru. To přes inject* metody funguje totiž jen v presenterech a nikde jinde. Jednoduše se vyplatí používat konstruktory vždy ;-)

Edit: hezké, jak na tyto klasické a i docela časté otázky odpoví vždy tolik lidí najednou :-)

Editoval David Kudera (9. 9. 2014 16:45)

David Matějka
Moderator | 6445
+
0
-

@Šaman v návodu není chyba, ten používá inject metody pouze u presenteru

Šaman
Člen | 2666
+
0
-

matej21 napsal(a):

@Šaman v návodu není chyba, ten používá inject metody pouze u presenteru

Aha, sorry, já ho nečetl :)