I have some Legacy classes. Many classes are instantiated using a Factory Class.
There is also a Singleton-Class.
In the future I want to replace them completely with the DIC. For the moment the codebase is to large to do this.
Now my goal is to inject the DI-Container into every Service instantiated by the Singleton class. The Singleton class has a static method with this signature.
final class Singleton
{
private static $singletonCache = array();
public static function getInstance($namespace, $className)
{
}
}
inside of this function I want to check for:
$instance = new $className();
if($instance instanceof ContainerAwareInterface)
{
// TODO: how do we get the container here
$instance->setContainer($container);
}
But how can I best get the container inside of my "singleton class", which is only called statically?
Another approach is to access the container globally when you need it:
public static function getInstance($namespace, $className)
{
$container = $_GLOBAL['kernel']->getContainer();
}
Of course there are sorts of things wrong with this approach but as long as you are transitioning then it's enough to get by.
Somewhere early in your bootstrapping code, but after the container is instantiated, you can pass the container to your singleton class:
Singleton::setContainer($container);
It would store the container in a static property:
final class Singleton
{
// ...
private static $container;
public static function setContainer(ContainerInterface $container)
{
self::$container = $container;
}
}
However, as you learned on the example of your singleton class, all global state gives you is headaches. Passing the container around (and using ContainerAware) is something to avoid. By passing the container to your services you're making them rely on the whole world of services. It's cleaner to only pass collaborator you actually need. It's also far easier to test.
Another solution is presented in this answer, which is pretty much the same as the other answer to this question, just using the global
keyword instead of the $_GLOBAL
array to access the kernel object.
public static function getInstance($namespace, $className)
{
global $kernel;
$container = $kernel->getContainer();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With