2

When we are using a SDK third party library of any service we can not change it and when this service requires a parameter as argument. Example:

/**
 * @param string $apiKey
 * @param int|null $timeout
 */
public function __construct($apiKey, $timeout = null)
{
    $this->client = new Client(
        new GuzzleClient(
            [
                'base_url' => 'https://api.urlapi/'
            ]
        ),
        $apiKey,
        $timeout
    );
}

In a custom module, we need to take this apiKey from a configuration and pass it as an argument in the creation of this object.

I would not like to instantiate with "new" of course, because of the high coupling.

My solution so far was to fabricate this object via Magento:

<?php
namespace MyVendor\MyModule\Model;

use ServiceVendor\Sdk\ClassNameFactory; // Create automatically

class MyModelExample
{
     protected $classNameFactory;

     public function __construct(
        ClassNameFactory $classNameFactory
     ){
         $apiKey = ''; // Get my apiKey from any other method.
         $this->classNameFactory = $classNameFactory->create([
             'apiKey' => $apiKey
         ]);
     }
}

This works fine in developer mode when we do not run the command:

bin/magento setup:di:compile

Because the create method of the \Magento\Framework\ObjectManager\Factory\Dynamic\Developer class is executed and the _resolveArguments method resolves this argument injection.

But if we run the command:

bin/magento setup:di:compile

This stops working because it is executed by the create method of the class: \Magento\Framework\ObjectManager\Factory\Compiled

And instead of injecting the apiKey argument an ObjectManager instance is injected. I think there is something missing for the di.xml file to work correctly.

It only works for both cases, if I pass with the key "0" of the array as well:

$this->classNameFactory = $classNameFactory->create([
     0 => $apiKey,
     'apiKey' => $apiKey
]);

I understand that even if it's working that way, it's not the best way to do it, and to ensure it's easy to create tests.

What do you suggest for the best way to work with this?

Thanks

1

Something like this maybe ?

$this->flagFactory->create(['data' => ['flag_code' => 'something']]);

How can data parameters be passed to a factory create( ) in Magento 2?

  • Hi, thank you for this reply. It did not work in developer mode and (without running the command: bin/magento setup:di:compile). $this->classNameFactory = $classNameFactory->create(['data' => ['api_key' => $apiKey]]); Exception: Missing required argument $apiKey of ServiceVendor\Sdk\ClassName I also tried passing the name in the format flagName and the same error persists. – Rafael Ortega Bueno Mar 3 '17 at 3:18
  • I also tested after running the command (bin/magento setup:di:compile), Now I do not get the same exception, however instead of the value of the apiKey is injected an instance of Magento\Framework\ObjectManagerInterface The same problem that I report above in my question remains. Thanks. – Rafael Ortega Bueno Mar 3 '17 at 3:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.