First Approach:
The cleanest way is to not take decisions in the constructor.
Let the di.xml
do that for you.
Let's say the core class you are using if a module is not present is Some\Core\ClassName
.
And the class that should use this core class us My\Custom\ClassName
.
And the class that might not exist is MyExtension\PerhapsNotInstalled\ClassThatMightNotExist
Make your class constructor like this:
public function __construct(
\Some\Core\ClassName $object
) {
$this->_object = $object;
}
Now, in your module MyExtension_PerhapsNotInstalled
di.xml
file add this:
<type name="My\Custom\ClassName">
<arguments>
<argument name="object" xsi:type="object">MyExtension\PerhapsNotInstalled\ClassThatMightNotExist</argument>
</arguments>
</type>
just make sure that MyExtension\PerhapsNotInstalled\ClassThatMightNotExist
extends the core class Some\Core\ClassName
.
This way, if the module MyExtension_PerhapsNotInstalled
is not installed, the original core class Some\Core\ClassName
will be used, otherwise MyExtension\PerhapsNotInstalled\ClassThatMightNotExist
will be used.
Second Approach:
If your extension that might not exist, is a third party extension that you cannot control, and you want your code to work with it and without it, you can do this (using the same notations as above):
Create your own class that acts as a factory:
Let's call it My\Module\Factory
<?php
namespace My\Module;
class Factory
{
protected $moduleManager;
protected $objectManager;
public function __construct(
\Magento\Framework\Module\Manager $moduleManager,
\Magento\Framework\ObjectManagerInterface $objectManager $objectManager
) {
$this->moduleManager = $moduleManager;
$this->objectManager = $objectManager;
}
public function create(array $data = array())
{
if ($this->_moduleManager->isEnabled('ThirdPartyExtension_PerhapsNotInstalled')) {
$instanceName = 'MyExtension\PerhapsNotInstalled\ClassThatMightNotExist';
} else {
$instanceName = 'Some\Core\ClassName';
}
return $this->objectManager->create($instanceName, $data);
}
}
You should inject this new class in the constructor of your My\Custom\ClassName
class and call the create
method from it to determine the class instance you need.
public function __construct(
\My\Module\Factory $factory
) {
$this->_object = $factory->create();
}
Note: This second approach is not really clean, because in theory your dependencies should be explicit and the composition should be done via di.xml
but I certainly understand the need.
Second Note: You are not violating any guidelines of not using the object manager, because OM is allowed in factories and you just created a factory.
And your class does not depend on the OM directly.
I didn't test the code, so watch out for syntax errors.
Ref : Magento2: Checking if a module exists, after being injected via class constructor
<type name="My\Custom\Builder">