Jak nejlíp nahradit $GLOBALS v Nette
- chikeet
- Člen | 160
Zdravím, upgraduju CMS z Nette 2.0 beta na 2.0.10 a snažím se o striktní DI. Konkrétně řeším, čím nahradit $GLOBALS, které se v aplikaci zatím používaly, a to pokud možno tak, aby to bylo co nejčistší, ale zároveň nebylo nutné kvůli tomu předávat všude celý container. Napadají mě dva způsoby řešení:
- Použít container[‚parameters‘] – pro každou původně globální proměnnou přidat nový parametr, který by byl defaultně prázdný a naplnil se až za běhu. Nevím ale, nakolik se tohle řešení shoduje s účelem containeru, připadá mi, že parameters by měly sloužit spíš k načtení konfigurace než k předávání proměnných mezi moduly.
- Použít služby – pro každou původně globální proměnnou napsat třídu (je jich jen pár a jsou to všechno objekty, takže by to snad nebyla až taková zvrhlost jako psát třídu třeba pro nějaký string). (Nebo případně jednu službu, která by uchovávala všechny původně globální proměnné, ale to už je asi prakticky totéž jako použít $GLOBALS, ne?). To by se mi i celkem líbilo, nebýt toho, že pokud se nepletu, k volání služby potřebuju mít dostupný container a předávat celý container všude, kde se původně používaly globální proměnné, se mi nechce.
Jaké by bylo v tomhle případě nejlepší řešení? Uvažuju správným směrem? Nebo mi něco uniká?
- Filip Procházka
- Moderator | 4668
Chápu správně, že jsi měl v globals parametry a objekty? Měl by jsi je nahradit službami, tyto služby registrovat do DI Containeru a předávat si je do konkrétních objektů.
Takže né
class Article
{
function save($title, $content)
{
$GLOBALS['db']->insert(...);
}
}
ani
class Article
{
private $container;
public __construct($container)
{
$this->container = $container;
}
function save($title, $content)
{
$this->container->db->insert(...);
}
}
ale tohle
class Article
{
private $db;
public __construct(DibiConnection $database) // například
{
$this->db = $database;
}
function save($title, $content)
{
$this->db->insert(...);
}
}
- ViPEr*CZ*
- Člen | 817
A ještě doplním, že je třeba možno udělat z Article taky službu.
A tzv. autowire se postará o to, aby při vytváření služba Article
dostala jinou službu (v tomto příkladu například spojení na
databázi).
A pokud by konstruktor Article měl namísto parametru instanci na objekt jen
nějakou proměnnou (například řetězec), tak si ho tam můžu taktéž
vztříknout v configu při vytváření služby ze třídy Article.