Chyba při injekci Nette\Security\User

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

Mám tu zajímavý problém s tímto modelem:

use Nette\Security as NS;

class UserModel extends Nette\Object implements NS\IAuthenticator
{
	/** @var Nette\Database\Context */
	protected $db;
	/** @var Nette\Security\User */
	protected $user;

	public function __construct(Nette\Database\Context $db, Nette\Security\User $user)
	{
		$this->db = $db;
		$this->user = $user;
	}
}

Aplikaci shodí injekce druhého parametru hláškou „Circular reference detected for services: user, 23_UserModel“. Když ho ale injektuju do modelu, který nemá v názvu „User“ tak bez problému. Netušíte někdo? v2.2RC4, 05–05–14

PS: proč v téhle nové verzi nefunguje @inject v modelu?

Editoval David Klouček (9. 5. 2014 18:56)

jiri.pudil
Nette Blogger | 1032
+
0
-

Netušíte někdo?

Viz upozornění v migration guide:

  • do Nette\Security\User se v konstruktoru předává autentikátor, pozor na kruhové závislosti

proč v téhle nové verzi nefunguje @inject v modelu?

Protože mimo presenter je preferovaný constructor injection. Pokud chceš injectování přes anotace povolit, musíš to udělat u daných služeb v konfiguraci (pomocí inject: on)

Tomáš Votruba
Moderator | 1114
+
0
-

Vypadá to, že máš implementaci user/authenticatoru, kam předáváš model. User → model, model → user a chyba je na světě.
Zkusil bych IAuthenticator implementovat samostatně, instanci User tam nepotřebuješ. Inspiraci můžeš shlédnout v sandboxu

Ad @inject – je od určité verze povolena pouze na presenterech, všude jinde bys měl pro předání závislostí použít konstruktor. Je k tomu pěkný cheat sheet

David Klouček
Člen | 57
+
0
-

Tomáš Votruba napsal(a):

Vypadá to, že máš implementaci user/authenticatoru, kam předáváš model. User → model, model → user a chyba je na světě.
Zkusil bych IAuthenticator implementovat samostatně, instanci User tam nepotřebuješ. Inspiraci můžeš shlédnout v sandboxu

Já to mam právě skoro stejně jako v tom sandboxu. Authenticátor v modelu. Logicky mi přijde, že to patří k sobě.. Takže to vlastně musim rozdělit a v modelu si vytvořit metodu, která bude pracovat s authenticatorem? V něm se ale taky musí pracovat s modelem, takže zase Circular reference.

Jiří Nápravník
Člen | 710
+
0
-

Máš to právě SKORO stejně.

Jde o to, že ty máš nějaký UserModule, který implementuje rozhraní authenticatoru a v jeho konstruktoru potřebuješ zároveň Nette\Security\User – či-li když ti pak vytváří tvojí DI kontejner objekt UserModel, tak vidí, že potřebuje Nette\Security\User, jenže Nette\Security\User potřebuje zase Authenticator a v tvém případě je Authenticator zase ta třída UserModel a tak neví co má vytvořit jak, protože je v kruhu.

Mělo by ti stačit udělat
UserModel, jako máš, ale smaž z něj to implements NS\IAtuhenticator
vytvoř nvoou třídu, která bude ten Authenticator a ten si pak předej v konstruktoru (pokud potřebuješ) jako si předáváš NS\User a pracuj s ním.

David Klouček
Člen | 57
+
0
-

Chápu. Ale samotná metoda autenticate v authenticatoru se potřebuje nějak dostat k DB, nejlíp využít ten UserModel a tim se to zas zacyklí. Můžu to vyřešit přímou komunikací s DB ale to se mi moc nelíbí.

Jiří Nápravník
Člen | 710
+
0
-

A potřebuješ vůbec tu NS\User v modelové třídě? Já jí tam třeba nemám ani koukám, prostě si přewdávám přímo identitu do metod v modelu, kde potřebuji.

No a když koukám na svůj authenticator, tak ja tam ten model cely nepoužívám, ale daávám s itam jen DAO, či-li v podstatě je to jakoby přímo ta práce s DB, jak zminujes

David Klouček
Člen | 57
+
0
-

Potřebuju tam uživatelem pracovat, budu ho teda taky předávat parametrem. Ale je to zbytečný, je to jenom kvůli tomu, že to jinak nejde.

Jiří Nápravník
Člen | 710
+
0
-

No budeš pracovat s uživatelem, či-li s jeho identitou ne (NS\User->getIdentity())? NS\User je v podstatě jen service, kteráá má v sobě

Jinak to jde, pokud ji tam potrebuejs tedy potřebuješ. Nedávat do autentifikatoru stejnou modelovou třídu, který vyžaduje NS\User, bud jinou nebo přímo se zeptat databáze.