I am actually trying to instanciate a class dynamically with these arguments.
Here is the code I use in class A
:
/** @var string $source */ $source = '\Foo\Bar\My\Class'; // Dynamic value that I am not aware because it is from other extensions /** @var bool $isClassLoadable */ $isClassLoadable = $this->definedClasses->isClassLoadable($source); if (!$isClassLoadable) { return false; } /** @var Model $model */ $model = $this->getModel(); // loaded model with data /** @var \Magento\Framework\Simplexml\Config $config */ $config = $this->getConfig(); // loaded configuration with data /** @var ProcessorInterface $processorInstance */ $processorInstance = $this->objectManager->create( $source, [ $model, $config, ] );
The \Foo\Bar\My\Class
class code:
public function __construct( Model $model, Config $config ) { $this->model = $model; $this->config = $config; \Zend_Debug::dump($this->model->debug()); \Zend_Debug::dump($this->config); }
Here my two parameters are an empty model and an empty configuration.
Questions
– Is it a good practice to use ObjectManager
to create class from a "string" ?
– If it is a "good practice" what is the way to keep my data between my class A
and the \Foo\Bar\My\Class
instanciation ?
EDIT
I am aware that using ObjectManager
is a bad practice and Factory
are here to avoid that but the $source
is from a configuration and maybe third part extensions, I don't know his value. I hardcoded it for the purpose of my example.
Best Answer
No, it's not a good practice to use the object manager.
Use a factory instead.
To get an instance of
\Foo\Bar\My\Class
you will need to use an instance of\Foo\Bar\My\ClassFactory
that will be automatically generated.I assume that the code you listed in the question is part of a class.
you should have in your class this:
Then you can instantiate your
\Foo\Bar\My\Class
like this:The
create
method takes as parameter an array, and the keys in this array must match the constructor argument names in the class you are instantiating.Your class accepts 2 parameters in the constructor called
$model
and$config
hence the array keysmodel
andconfig
.[EDIT]
In case your class acts as a factory you can use
ObjectManager
.I think you should move the code that actually instantiates
$source
in a separate factory (that's not autogenerated) and you are allowed there to use the OM.And you can inject that general factory in your class and have something like this