Actuellement je développe une extension Shopware 6 basée sur Symfony. Ce que je ne comprends pas, c'est comment implémenter des classes abstraites et l'injection de dépendances.
Je souhaite donc pouvoir refactoriser le code et utiliser ces méthodes souvent, mais dans un autre contexte (en utilisant un autre référentiel)
<?php declare(strict_types=1); namespace WShopService; use ShopwareCoreFrameworkContext; use ShopwareCoreFrameworkDataAbstractionLayerSearchCriteria; use ShopwareCoreFrameworkDataAbstractionLayerEntityRepository; use ShopwareCoreFrameworkDataAbstractionLayerSearchFilterEqualsFilter; use ShopwareCoreFrameworkUuidUuid; /** * Service for writing Products */ class ProductService { private EntityRepository $productRepository; private MediaImageService $mediaImageService; private EntityRepository $productMediaRepository; public function __construct( EntityRepository $productRepository, MediaImageService $mediaImageService, EntityRepository $productMediaRepository ) { $this->productRepository = $productRepository; $this->mediaImageService = $mediaImageService; $this->productMediaRepository = $productMediaRepository; } private function createProduct(array $data, Context $context = null): void { $context = $context ?? Context::createDefaultContext(); $this->productRepository->create([ $data ], $context); } public function updateProduct(array $data): void { $this->productRepository->update([$data], Context::createDefaultContext()); } public function getExistingProductId(string $productNumber): ?string { $criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('productNumber', $productNumber)); return $this->productRepository->searchIds($criteria, Context::createDefaultContext())->firstId(); } }
Comme vous pouvez le voir, il y a une injection de dépendances à l'intérieur de la construction (référentiel produit). Maintenant, ma question est la suivante : comment puis-je créer une classe abstraite, c'est-à-dire stocker ces méthodes, mais la classe enfant « remplacera » la construction parent par le référentiel requis ? Par exemple, je souhaite utiliser la méthode getDataId (maintenant appelée getExistingProductId, mais sera refactorisée et renommée dans la classe abstraite) sur le Product Repository, mais pour la classe suivante, je souhaite utiliser la même chose sur la Category Méthodes du référentiel ?
Service.xml également connu sous le nom d'injecteur de dépendances
<service id="wshop_product_service" class="WShopServiceProductService"> <argument type="service" id="product.repository"/> <argument id="wshop_media_image_service" type="service"/> <argument type="service" id="product_media.repository"/> </service>
Je suis nouveau sur la POO. Veuillez fournir de bons exemples et des explications de code. Merci!
Si j'ai bien compris, vous voulez que seul le premier paramètre soit interchangeable, et les 3 méthodes de l'exemple doivent être implémentées dans l'abstraction. Voici une idée.
Résumé :
Vous obtenez le référentiel dans le constructeur et implémentez toutes les méthodes courantes concernant le référentiel commun dans l'abstraction.
getDataId
méthodes que vous souhaitez implémenter dans votre classe étendue car vous utilisez des conditions spécifiques (vraisemblablement) pour chaque méthode. Il vous suffit donc de forcer l'implémentation dans la classe étendue en définissant une signature abstraite.Votre niveau de service :
Dans la classe d'extension, vous transmettez uniquement le référentiel au constructeur parent car les autres services injectés ne sont utilisés que dans cette instance spécifique. Vous pouvez implémenter
getDataId
并使用该条件调用受保护的(因为它只能由扩展使用)searchId
où vous créez une condition spécifique et appelez la méthode protégée (car elle ne peut être utilisée que par les extensions)searchId
avec cette condition.