I remember that some time ago I read in a book that the never enough praised minds that “created” the InterNet saw the first impact of their creation in the impossibility, from that moment on, for anyone not to know something: free access to information would have meant the end of ignorance. Human laziness was not counted it seems.
The above consideration came to me reading this article on DevTrends by Paul Hiles that seemed to scream to me for my goofy usage of the Inversion of Control(IoC) pattern to do dependency injection.
My error
Looking at a class like Main
what I’ve done to inject its dependency on the Bot
class is this
protected function __construct()
{
// set the called class
$this->calledClassName = get_called_class();
// init the root namespace and root folder path
$this->setRoots();
// get controllers information
$this->bot = IoC::make('Bot', array($this->mainFilePath, $this->mainClassNamespace));
// $this->bot = new Bot($this->mainFilePath, $this->
// namespace);
$this->controllers = array();
}
Which does work but
- The implementation of the
Bot
class resolution has to be made somewhere before the__construct
method is called - No IoC container means the class will not work and the class is strongly coupled to it
- The class has an internal and not explicit dependency on the IoC container
And I’m sure many more misfortunes.
Where to move now?
What I get from the article is that any class should have injectable dependencies and that those should be visibile in its constructor arguments right away. Thinking of my Main
class it doesn’t even have a public constructor but relies, instead, on the Singleton pattern for its implementation.
Further research on my side reveals that the Singleton is considered and anti-pattern by many that favors ease of access over a rigid and non-testable implementation.
The latter point I’ve come to term with using IoC pattern. In the wrong way it seems.
Injecting a singleton
The Singleton pattern hides the __construct
method in a protected
or private
method and hence any injection should be made either via the getInstance()
method
public static function getInstance($injectableDependency1, $injectableDependency2, $injectableDependency3, ...);
or defining some methods in the class, magic or not, to set and probably get that instance
public static function setDependency1($value);
public static function setDependency2($value);
public static function setDependency3($value);
public static function getDependency1();
public static function getDependency2();
public static function getDependency3();
all public and static.
All this smells bad to me.
Do I need a singleton?
Before the how I’ll think about the why. I’ve initially implemented the Main
class as a singleton following along the same lines that make many tutorials about WordPress development state that the main plugin class should be a singleton; this is done essentially to make the plugin survive in the global space and not having to create a new, and resource expensive, instance of it anytime.
So I do need something that works like a singleton.
I love StackOverflow
This answer on StackOverflow gave me an idea I could follow along about using the Factory Method to instantiate the main plugin class.
I do not need a singleton. I need a factory.