To me, I reckon that is the best practice and even if I agree with you that it doesn't look right and implies a high risk of error when calling the parent constructor.
I'm assuming that this is the best practice by just looking at the Magento 2 core code, taking one of the most (probably the most) used class of Magento: \Magento\Catalog\Model\Product
. This class extends \Magento\Catalog\Model\AbstractModel
.
And here is the constructor:
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
AttributeValueFactory $customAttributeFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService,
Product\Url $url,
Product\Link $productLink,
\Magento\Catalog\Model\Product\Configuration\Item\OptionFactory $itemOptionFactory,
\Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory $stockItemFactory,
\Magento\Catalog\Model\Product\OptionFactory $catalogProductOptionFactory,
\Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
\Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus,
\Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig,
Product\Type $catalogProductType,
\Magento\Framework\Module\Manager $moduleManager,
\Magento\Catalog\Helper\Product $catalogProduct,
\Magento\Catalog\Model\ResourceModel\Product $resource,
\Magento\Catalog\Model\ResourceModel\Product\Collection $resourceCollection,
\Magento\Framework\Data\CollectionFactory $collectionFactory,
\Magento\Framework\Filesystem $filesystem,
\Magento\Framework\Indexer\IndexerRegistry $indexerRegistry,
\Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
\Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor,
\Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
CategoryRepositoryInterface $categoryRepository,
Product\Image\CacheFactory $imageCacheFactory,
\Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider,
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory,
\Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory,
EntryConverterPool $mediaGalleryEntryConverterPool,
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor,
array $data = []
) {
$this->metadataService = $metadataService;
$this->_itemOptionFactory = $itemOptionFactory;
$this->_stockItemFactory = $stockItemFactory;
$this->optionFactory = $catalogProductOptionFactory;
$this->_catalogProductVisibility = $catalogProductVisibility;
$this->_catalogProductStatus = $catalogProductStatus;
$this->_catalogProductMediaConfig = $catalogProductMediaConfig;
$this->_catalogProductType = $catalogProductType;
$this->moduleManager = $moduleManager;
$this->_catalogProduct = $catalogProduct;
$this->_collectionFactory = $collectionFactory;
$this->_urlModel = $url;
$this->_linkInstance = $productLink;
$this->_filesystem = $filesystem;
$this->indexerRegistry = $indexerRegistry;
$this->_productFlatIndexerProcessor = $productFlatIndexerProcessor;
$this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
$this->_productEavIndexerProcessor = $productEavIndexerProcessor;
$this->categoryRepository = $categoryRepository;
$this->imageCacheFactory = $imageCacheFactory;
$this->entityCollectionProvider = $entityCollectionProvider;
$this->linkTypeProvider = $linkTypeProvider;
$this->productLinkFactory = $productLinkFactory;
$this->productLinkExtensionFactory = $productLinkExtensionFactory;
$this->mediaGalleryEntryConverterPool = $mediaGalleryEntryConverterPool;
$this->dataObjectHelper = $dataObjectHelper;
$this->joinProcessor = $joinProcessor;
parent::__construct(
$context,
$registry,
$extensionFactory,
$customAttributeFactory,
$storeManager,
$resource,
$resourceCollection,
$data
);
}
Yep, that's a huge constructor and the call to its parent constructor is also pretty big.
So, taking that class, which is to me, one of the most used class over Magento (apart from Abstract classes obviously and very high level classes), if the Magento team has not used a different solution at least to make that easier to read for us, I reckon that's because that's how it has to be done.