Nepovinné závislosti extensions

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

Ahoj, narazil jsem na takový zajímavý problém. Mám několik extensions (pro účel ukázky to budou Events a Database). Každá může fungovat zvlášť, ale pokud jsou zaregistrované dohromady, tak si předají nějaké závislosti (např. pokud je Events současně s Database, tak se provede $database->setEventManager($eventManager), kde $eventManager je služba registrovaná v Events).

Moje otázka se týká spíše návrhu aplikace a extensions jako takových, kód si napíšu klidně sám. Jde mi o to, jak takovéhle věci řešit. Napadly mě zatím tři řešení:

1) CompilerExtension::beforeCompile()

V beforeCompile si zjistím, zda je registrovaná daná služba a předám si jí přes setter, např.:

public function beforeCompile()
{
    $builder = $this->getContainerBuilder();
    $extensions = $this->compiler->getExtensions('\\App\\DatabaseExtension');
    if (count($extensions)) {
        $builder->getDefinition($this->prefix('database'))
            ->addSetup('setEventManager');
    }
}

2) Container inject

V konstruktoru si předám kontejner a zkusím vytáhnout danou službu, např.:

class Database
{
	public function __construct(DI\Container $container) {
		if ($service = $container->getByType('\\App\EventManager')) {
			$this->setEventManager($service);
		}
	}
}

3) Vlastní ContainerBuilder

Rozšířít si ContainerBuilder a zavést do něj nějakým způsobem podporu pro nepovinné závislosti a tyhle věci pak řešit přímo v CompilerExtension nějakýma callbackama, např:

class DatabaseExtension extends ExtensionWithDependencies // extends CompilerExtension
{
	public function getOptionalDependencies() {
		return [
			'\\App\\EventsExtension' => function (DatabaseExtension $databaseExtension, EventsExtension $eventsExtension) {
				$databaseExtension->getContainerBuilder()
					->getDefinition($databaseExtension->prefix('database'))
					->addSetup('setEventManager');
			}
		];
	}
}

Shrnutí

Všechno jsou to jen nápady, zajímá mě váš názor, jestli jste někdy něco podobného řešili, nebo jiný návrh, jak takovou strukturu postavit.

Díky, @greeny

Editoval greeny (2. 3. 2015 17:22)

Filip Procházka
Moderator | 4668
+
0
-

Z těch 3 řešení které jsi sepsal je čisté pouze to první řešení.

Dále pak záleží na směru závislosti. V jiných případech můžeš použití ještě třeba tagy.

enumag
Člen | 2118
+
0
-

Můžeš ty závislosti mít jako nepovinné, tedy __construct(Foo $foo = NULL).