PHP - Container de dependente

Am scris o clasa simpla ce reprezinta un container de dependente( dependency injection container ), as vrea sa stiu daca sunt pe calea cea buna, incerc sa aplic SOLID in tot ceea ce fac, insa nu am asa de multa experienta.

<?php namespace Classes;

class Container
{
	/**
	 * An array that contains container's elements
	 * @var array
	 */
	private $container = [];

	/**
	 * An array that contains the instances created.
	 * @var array
	 */
	private $instances = [];

	/**
	 * Add a new element in the container.
	 * @param  string   $name 
	 * @param  callable $callable
	 * @throws \Exception
	 */
	public function bind($name, callable $callable)
	{
		if (is_string($name)) {
			$this->container[$name] = $callable;
		} else {
			throw new \Exception('Container: You have to provide a valid name in the bind method');
		}
	}

	/**
	 * Resolve an element from container.
	 * @param  string $name
	 * @return object
	 */
	public function resolve($name)
	{
		if (isset($this->container[$name])) {
			return call_user_func($this->container[$name]);
		} else {
			throw new \Exception('Container: The '. $name . ' was not found in the container');
		}
	}

	/**
	 * Create instances of elements from container.
	 * @param  string $name
	 */
	public function singleton($name) 
	{
		$this->instances[$name] = $this->resolve($name);
	}

	/**
	 * Use the required instance.
	 * @param  string $name
	 * @return object
	 * @throws \Exception
	 */
	public function resolveSingleton($name)
	{
		if (isset($this->instances[$name])) {
			return $this->instances[$name];
		} else {
			throw new \Exception('Container: The '. $name . ' was not found in the container');
		}		
	}
}
  • grija, ca un container de obiecte NU este DI; vei ajunge sa injectezi acel container in clasele tale; cu DI, injectezi obiectele direct, sistemul ocupandu-se de instantiere; injectarea directa a unui container nu este considerata o strategie buna de a decupla sistemul, dar e un inceput; daca esti de acord…
  • clasa ta poate fi clonata; fa-o singleton adevarat, cu proprietati statice; nu permite mai multe instatieri a container-ului; va fi prea seducator pt workaround-uri;
  • de ce 2 proprietati? iti trebuie numai instances;
  • clasa ta permite crearea de obiecte noi sau numai singleton?
  • numeste-ti metodele ca lumea, nu asa abstract;
  • de ce numai callable?
  • n-as arunca exceptii, as returna false; ma pui sa fac try/catch de fiece data cand vreau un obiect; de fapt, de ce nu - cererea unui obiect inexistent ar trebui sa crape aplicatia;
  • vezi cum face Pimple. am inteles ca nu-i rau
1 Like

Un DiC omoara SOLID.

Pentru un SOLID solid, foloseste DI (dependency inversion) cu injectie manuala a dependintelor. Eu unul prefer via constructor, deoarece atunci vezi clar dependintele, iar atunci cand un constructor devine prea complicat (primeste prea multi parametri):

  1. mai intai ma gandesc daca nu cumva doi sau mai multi parametri pot fi grupati intr-o alta clasa deoarece reprezinta un concept din application domain
  2. daca nu si nu, folosesc builder pattern

Din experientele mele, majoritatea se rezolva cu 1, la 2 se ajunge destul de rar (gen 1 data la 100-400 de clase).

DiC il tolerez in afara bibliotecii centrale a aplicatiei (cea care implementeaza application domain, care are business value), ca mijloc rapid de “masacrare” a oricarei biblioteci sau framework in care n-am incredere.

Pentru detalii, vezi raspunsurile de pe un alt topic:

3 Likes