Problem jest następujący. Mam klasę do której wstrzykuje zależności za pomocą konstruktora. W jednej zależnych klas jednym z parametrów konstruktora jest zmienna typu string np. $modulelId, która jest potrzebna do stworzenia obiektu, którego będę używał wewnątrz innej klasy. Rejestrację zależności oraz tworzenie instancji wymaganych obiektów chciałem odseparować do innej warstwy, w której wykorzystuję kontener DI. W chwili użycia obiektu, do którego inicjalizacji potrzebna jest zmienna $moduleId, np brana z pętli for wewnątrz innej klasy, nie mogę tego zrobić za pomocą DI kontenera. Musi to zostać wywołane wewnątrz klasy, która posiada zmienne $moduleId. Czy w takim przypadku można olać DI i użyć po prostu new czy lepiej wywalić z konstruktora parametr $moduleId i zrobić setter, który będzie używany przez klasę posiadającą zmienne $moduleId? Wtedy tworzeniem wszystkich instancji mógłby się zająć kontener DI. Z drugiej jednak strony taki stan utworzonego obiektu bez ustawionej zmiennej $moduleId jest sytuacją niepożądaną i tak naprawdę obiekt od początku jego inicjalizacji powinien mieć ten atrybut ustawiony.
Jak prawidłowo powinienem zaprojektować strukturę klas, tak aby było to zgodne z IoC?
Przykład:
<?php
class ModuleManager
{
private $modulePropertyGetter;
private $moduleSearcher;
// pierwszy sposób
public function __construct(ModuleSearcherInterface $moduleSearcher)
{
$this->moduleSearcher = $moduleSearcher;
}
// drugi sposób z zależnością w konstruktorze
public function __construct(ModulePropertyGetterInterface $modulePropertyGetter, ModuleSearcherInterface $moduleSearcher)
{
$this->modulePropertyGetter = $modulePropertyGetter;
$this->moduleSearcher = $moduleSearcher;
}
public function getModulesNames()
{
$modules = $this->moduleSearcher>getModules();
$modulesNames = [];
foreach ($modules as $moduleId) {
// pierwszy sposób
$modulePropertyGetter = new ModulePropertyGetter($moduleId);
$modulesNames[] = $modulePropertyGetter->getName();
// lub
// drugi sposób
$this->modulePropertyGetter->setModule($moduleId);
$modulesNames[] = $this->modulePropertyGetter->getName();
}
}
}
class ModulePropertyGetter implements ModulePropertyGetterInterface
{
private $moduleId;
private $someClass;
// pierwszy sposób z konstruktorem
public function __construct($moduleId, SomeClassInterface $someClass)
{
$this->moduleId = $moduleId;
$this->someClass = $someClass;
}
// drugi sposób przez setter
public function setModule($moduleId)
{
$this->moduleId = $moduleId;
}
public function getName();
{
/** do something */
return $name;
}
/**
Inne metody używające $this->moduleId;
*/
}
// Wykonanie z DI
$contaniner = new DIContainer();
$conteiner->registerDependencies(/** dependencies */);
$moduleManager = $container->get('ModuleManager');