how to get presenter factory from container

alnux
Member | 139
+
0
-

Im trying to get presenters list from container just like tracy DIC list is there a way to do this or necessary i have to use Nette\Utils\Finder to find presenters classes???

really thanks

mystik
Member | 312
+
0
-

Do you register your presenters in DI or do you use default behaviour where presenters are included by PresenterFactory when needed?

If you register your presenters in DI container then you can use $container->findByType(Presenter::class) it return array of service names.

alnux
Member | 139
+
0
-

Hi @Mistik i'm using default mapping in the neon config file
Thanks for your help

mystik
Member | 312
+
+1
-

If you ise default behaviour then you have to find presenters another way. Or you can use search extension of Nette DI to automatically register them to DI.

jeremy
Member | 54
+
0
-

I used decorator to add tags to my base presenter and any presenter extending that base presenter automatically gets the tags too.

Neon config:

decorator:
	Backend\Presenters\BasePresenter:
		tags: [presenter: 'Backend']
	Frontend\Presenters\BasePresenter:
		tags: [presenter: 'Frontend']

If you don't want a specific presenter (like Error4xx) to be included then you can set the tag for that presenter to null:

decorator:
	Backend\Presenters\Error4xxPresenter:
		tags: [presenter: null]
	Frontend\Presenters\Error4xxPresenter:
		tags: [presenter: null]
	Backend\Presenters\BasePresenter:
		tags: [presenter: 'Backend']
	Frontend\Presenters\BasePresenter:
		tags: [presenter: 'Frontend']

My config is little bit different, but this should give you an idea.

Then I have an extension that finds all the presenters:

final class Presenters extends CompilerExtension {
	public function loadConfiguration(): void {
		$builder = $this->getContainerBuilder();

		$builder->addDefinition($this->name)
			->setFactory(App\Services\Presenters::class);
	}

	public function beforeCompile(): void {
		$builder = $this->getContainerBuilder();
		$presentersByTag = $builder->findByTag('presenter');
		$presenters = [];

		foreach ($presentersByTag as $presenter => $module) { // $module = value of the tag 'presenter'
			if (!$module) {
				continue;
			}

			$definition = $builder->getDefinition($presenter);

			$presenters[$module][] = (new \ReflectionClass($definition->getType()))->getShortName();
		}

		$builder->getDefinition($this->name)->setArgument('presenters', $presenters); // Pass all the found presenters to the service constructor
	}
}

Again this is a simplified example of my code, just to give you an idea.

Last edited by jeremy (2023-09-03 15:29)

alnux
Member | 139
+
0
-

jeremy wrote:

I used decorator to add tags to my base presenter and any presenter extending that base presenter automatically gets the tags too.

Neon config:

decorator:
	Backend\Presenters\BasePresenter:
		tags: [presenter: 'Backend']
	Frontend\Presenters\BasePresenter:
		tags: [presenter: 'Frontend']

If you don't want a specific presenter (like Error4xx) to be included then you can set the tag for that presenter to null:

decorator:
	Backend\Presenters\Error4xxPresenter:
		tags: [presenter: null]
	Frontend\Presenters\Error4xxPresenter:
		tags: [presenter: null]
	Backend\Presenters\BasePresenter:
		tags: [presenter: 'Backend']
	Frontend\Presenters\BasePresenter:
		tags: [presenter: 'Frontend']

My config is little bit different, but this should give you an idea.

Then I have an extension that finds all the presenters:

final class Presenters extends CompilerExtension {
	public function loadConfiguration(): void {
		$builder = $this->getContainerBuilder();

		$builder->addDefinition($this->name)
			->setFactory(App\Services\Presenters::class);
	}

	public function beforeCompile(): void {
		$builder = $this->getContainerBuilder();
		$presentersByTag = $builder->findByTag('presenter');
		$presenters = [];

		foreach ($presentersByTag as $presenter => $module) { // $module = value of the tag 'presenter'
			if (!$module) {
				continue;
			}

			$definition = $builder->getDefinition($presenter);

			$presenters[$module][] = (new \ReflectionClass($definition->getType()))->getShortName();
		}

		$builder->getDefinition($this->name)->setArgument('presenters', $presenters); // Pass all the found presenters to the service constructor
	}
}

Again this is a simplified example of my code, just to give you an idea.

thanks @jeremy, it give me some ideas. you are a crack

alnux
Member | 139
+
0
-

mystik wrote:

If you ise default behaviour then you have to find presenters another way. Or you can use search extension of Nette DI to automatically register them to DI.

really thanks @Mistik you are help was great