Ako v extension zaregistrovat tovarnicku na komponentu?

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

Caute,
Neviete mi poradit ako v extension zaregistrujem tovarnicku na komponentu? Mam nejaku komponentu:

class MarkListControl extends BaseControl
{
	/** @var  bool */
	public $ajaxRequest = TRUE;

	...
}


/**
 * IMarkListControl
 */
interface IMarkListControl
{
	/**
	 * @return MarkListControl
	 */
	public function create();
}

A chcel by som v extension vytvorit tovarnicku na tento sposob:

MarkListControl:
	create: \NasExt\Controls\MarkListControl()
	implement: \NasExt\Controls\IMarkListControl
	setup:
		- $ajaxRequest(TRUE)
class MarkListControlExtension extends CompilerExtension
{

	/** @var array */
	public $defaults = array(
		'ajaxRequest' => TRUE,
	);

	public function loadConfiguration()
	{
		$builder = $this->getContainerBuilder();

		$config = $this->getConfig($this->defaults);

		$builder->...
		// ako vytvorim tovarnicku podla vzoru v neone?
	}

	...
}
Michal Vyšinský
Člen | 608
+
0
-

Ahoj,
myslím, že takto:

$builder->addDefinition($this->prefix('articlesList'))
    ->setClass('MyBlog\Components\ArticlesList', array($this->prefix('@articles')))
    ->addSetup('setPostsPerPage', $config['postsPerPage'])
    ->setShared(FALSE)->setAutowired(FALSE); // ze služby se stane továrnička

Viz: https://doc.nette.org/…n/extensions

David Matějka
Moderator | 6445
+
+1
-

to, co pise CherryBoss je pro klasicke tovarnicky, ty chces asi vytvorit DIC tovarnicku z rozhrani, to jde takhle:

$builder->addDefinition($this->prefix('fooFactory'))
->setImplement('FooFactory');

to je ta nejjednodussi forma, pak tam muzes klasicky pridavat ->addSetup() apod. jen nevim, jak se provede zapis do clensky promenny v extensionu, ja na vsechno pouzivam settery

EDIT: autowired a shared je defaultne true a true taky musi byt, nekdy se to vsak vypina, tak to budes muset rucne zpet nastavit na true

Editoval matej21 (11. 10. 2013 16:08)

duskohu
Člen | 778
+
0
-

Och, do dokumentacie som sa uplne zabudol pozriet :-P, Dakujem.

Filip Procházka
Moderator | 4668
+
0
-

to je ta nejjednodussi forma, pak tam muzes klasicky pridavat ->addSetup() apod. jen nevim, jak se provede zapis do clensky promenny v extensionu, ja na vsechno pouzivam settery

Úplně stejně jako v configu :)

$builder->addDefinition($this->prefix('fooFactory'))
	->setImplement('FooFactory')
	->addSetup('$ajaxRequest', array($config['ajaxRequest']));
pave.kucera
Člen | 122
+
0
-

A kdybys náhodou potřeboval továrničce předat parametr, tak viz https://gist.github.com/…cera/6208889#…

duskohu
Člen | 778
+
0
-

Dakujem pani, vsetky navrhovane riesenia su poucne :-)

duskohu
Člen | 778
+
0
-

Este riesim jeden problem. Ani neviem ci sa to takto riesi, ak nie budem rad ak mi navrhnete nieco cistejsie. Ako podstrcit vytvorenej tovarnicke sluzbu. Dajme tomu ze moja tovarnicka potrebuje sluzbu:

class MarkListControl extends BaseControl
{
	/** @var NasExt\Controls\MarkListControl\IStorage */
	private $controlStorage;

	/**
	 * @param NasExt\Controls\MarkListControl\IStorage $storage
	 */
	public function __construct(NasExt\Controls\MarkListControl\IStorage $storage)
	{
		parent::__construct();
		$this->storage = $storage;
	}
}


/**
 * IMarkListControl
 */
interface IMarkListControl
{

	/**
	 * @return MarkListControl
	 */
	public function create();
}

Myslienka je taka ze by som chcel podstrcit tovarnicke vlastne storage implementujuce Istorage, rovnako ako to robim s $ajaxRequest. A pokial myStorage nepodstrcim tak extension vyroby svoje defaultne storage a preda ho tovarnicke. Takze:

services:
	myStorage: MyStorage
nasext.markList:
	ajaxRequest: TRUE
	storage: @myStorage
class MarkListControlExtension extends CompilerExtension
{

	/** @var array */
	public $defaults = array(
		'ajaxRequest' => TRUE,
		'storage' => FALSE,
	);


	public function loadConfiguration()
	{
		$config = $this->getConfig($this->defaults);

		$builder = $this->getContainerBuilder();

		$storage = $config['storage'];
		if ($storage == FALSE) {
			$builder->addDefinition($this->prefix('storage'))
				->setClass('NasExt\Controls\MarkListControl\Storage')
				->setAutowired(FALSE);
		} else {
			if (!$storage instanceof IStorage) {
				throw new InvalidStorageException('Storage must be Instance of "NasExt\Controls\MarkListControl\IStorage".');
			}
		}

		$builder->addDefinition($this->prefix('markListControl'))
			->setImplement('NasExt\Controls\MarkListControl\IMarkListControl')
			// Ako predat constructoru $storage ?
			->addSetup('setAjaxRequest', array($config['ajaxRequest']));
	}
}

Editoval duskohu (12. 10. 2013 1:01)

duskohu
Člen | 778
+
0
-

Tak som na to prisiel. V podstate ked podstrcim extension MyStorage tak pouzije to, inak si vytvori svoje a pouzije svoje interne. Len neviem ci je to spravne.

services:
    myStorage: MyStorage
nasext.markList:
    ajaxRequest: TRUE
    storage: @myStorage
	public $defaults = array(
		'ajaxRequest' => TRUE,
		'storage' => FALSE,
	);


	public function loadConfiguration()
	{
		$config = $this->getConfig($this->defaults);

		$builder = $this->getContainerBuilder();

		$storage = $config['storage'];
		if ($storage == FALSE) {
			$builder->addDefinition($this->prefix('storage'))
				->setClass('NasExt\Controls\MarkListControl\Storage')
				->setAutowired(FALSE);

			$storage = $this->prefix('@storage');
		}

		$builder->addDefinition($this->prefix('markListControl'))
			->setImplement('NasExt\Controls\MarkListControl\IMarkListControl')
			->setFactory('NasExt\Controls\MarkListControl\MarkListControl', array($storage))
			->addSetup('setAjaxRequest', array($config['ajaxRequest']));
	}