2

I am trying to inject a CollectionFactory object into a Plugin like this:

/**
 * PopulateCustomerCards constructor.
 * @param CardCollectionFactory $cardCollectionFactory
 */
public function __construct(
    CardCollectionFactory $cardCollectionFactory
) {
    $this->cardCollectionFactory = $cardCollectionFactory;
}

I also create the Collection class like this:

class Collection extends Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    public function doSomething()
    {
        /* ... some magic is done here */
    }
}

When I run setup:di:compile the CardCollectionFactory is created like this:

/**
 * Factory class for @see \My\Module\Model\ResourceModel\Card\Collection
 */
class CollectionFactory
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $_instanceName = null;

    /**
     * Factory constructor
     *
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param string $instanceName
     */
    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\My\\Module\\Model\\ResourceModel\\Card\\Collection')
    {
        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
    }

    /**
     * Create class instance with specified parameters
     *
     * @param array $data
     * @return \My\Module\Model\ResourceModel\Card\Collection
     */
    public function create(array $data = array())
    {
        return $this->_objectManager->create($this->_instanceName, $data);
    }
}

The problem is when I run the code, file Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection breaks at line:

    $this->setConnection($this->getResource()->getConnection());

Because \Magento\Framework\DB\Adapter\AdapterInterface $connection = null is not being injected in the constructor.

1

Looks like the collection is not initialized properly. It should have knowledge about model and resource model. Add the following method to the custom collection class:

protected function _construct()
{
    $this->_init('My\Module\Model\Card', 'My\Module\Model\ResourceModel\Card');
}
|improve this answer|||||
1

I may be off base here, but one thing you need to recall with the auto-generated factories is I think they only work for classes where dependency injection can provide all the constructor arguments. For example, if you need to create products where the constructor requires a product ID, the default factory won't work - the create() method needs to be create($productId).

In this case, the base abstract collection class takes 'connection' as a constructor argument, with a default value of 'null'. See https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php#L116

I am wondering if the problem is the connection is not being provided and needs to, or the di.xml setup for some reason is not providing the connection (I am not familiar with this level of code - so just trying to provide a hint, not a complete solution).

But it is something to watch out for. It looks like the connection needs to be provided, but is not. (Another possible reason is the argument type of the abstract collection does not match the di.xml file.)

|improve this answer|||||
  • Thanks Alan, but it was an issue of not initializing the collection with the corresponding model and resourceModel. – awavi Dec 10 '15 at 5:17
  • Actually, connection can be taken either directly from collection construct arguments, or from related resource model (usual scenario). – Alex Paliarush Dec 10 '15 at 7:21

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.