How to Create Model Factory for Custom Module in Magento 2

customdependency-injectionfactorymagento-2.1model

Hi i am trying to collect some data from the database but the create method of the injected factory fails and no errors are showed.
Here are my classes.

magento\app\code\Cosmo\Basemodule\Model\DatiInterface.php

<?php
namespace Cosmo\Basemodule\Model;
interface DatiInterface
{

}

magento\app\code\Cosmo\Basemodule\Model\Dati.php

namespace Cosmo\Basemodule\Model;

use Magento\Framework\Model\AbstractModel;
use Magento\Framework\DataObject\IdentityInterface;
class Dati extends AbstractModel implements DatiInterface, IdentityInterface
{
    protected function _construct()
    {
        $this->_init('Cosmo\Basemodule\Model\ResourceModel\Dati');
    }

    public function getIdentities()
    {
       //todo
    }
}

magento\app\code\Cosmo\Basemodule\Model\ResourceModel\Dati.php

<?php
namespace Cosmo\Basemodule\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class News extends AbstractDb
{
    /**
     * Define main table
     */
    protected function _construct()
    {
        $this->_init('exampletable', 'entity_id');
    }
}

magento\app\code\Cosmo\Basemodule\Model\ResourceModel\Dati\Collection.php

<?php
namespace Cosmo\Basemodule\Model\ResourceModel\Dati;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    /**
     * Define model & resource model
     */
    protected function _construct()
    {
        $this->_init(
            'Cosmo\Basemodule\Model\Dati',
            'Cosmo\Basemodule\Model\ResourceModel\Dati'
        );
    }
}

And then block where i inject the factory
magento\app\code\Cosmo\Basemodule\Block\Main.php

 <?php
 namespace Cosmo\Basemodule\Block;

 use Magento\Framework\View\Element\Template\Context;
 use Cosmo\Basemodule\Model\DatiFactory;

 class Main extends \Magento\Framework\View\Element\Template
 {
    protected $_datiFactory;

    public  function __construct(Context $context, DatiFactory $datiFactory)
    {
        parent::__construct($context);
        $this->_datiFactory = $datiFactory;
    }

    public function _prepareLayout()
    {
        echo 'pippo<br \>';
        $dati = $this->_datiFactory->create();
        var_dump($dati->getCollection());
        exit();
    }
}

I tried in many ways but create() fails and then nothing is executed.

Best Answer

The problem that I see with your code is that in your call to parent::__construct, you are missing the $data = [] argument. Try changing your code to this:

class Main extends \Magento\Framework\View\Element\Template
{
    protected $_datiFactory;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        DatiFactory $datiFactory,
        array $data = []
    )
    {
        parent::__construct($context, $data);
        $this->_datiFactory = $datiFactory;
    }
}

After you have made that change, clear your var/generation and var/di directories.

Even though $data is an optional argument, it still need to be included in your arguments for your constructor for proper creation of the interceptor class.

Additionally, have you created the class Cosmo\Basemodule\Model\ResourceModel\Dati? I don't see it in the various blocks of code that you posted. If you forgot to create that class, that will also be a problem.