Question

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.

Was it helpful?

Solution

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');
}

OTHER TIPS

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.)

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top