目前我正在開發基于 Symfony 的 Shopware 6 擴展。我不明白的是如何實作抽象類和依賴注入。
所以我希望能夠重構代碼,并經常使用這些方法,但在另一個背景關系中(使用另一個存盤庫)
<?php
declare(strict_types=1);
namespace WShop\Service;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Uuid\Uuid;
/**
* 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();
}
}
如您所見,構造(產品存盤庫)內部存在依賴注入。現在我的問題是,我如何能夠創建抽象類,即存盤這些方法,但是子類將使用所需的存盤庫來“重寫”父構造?例如,我想在產品存盤庫上使用getDataId(現在稱為 getExistingProductId,但將在抽象類中重構和重命名)方法,但是對于下一個類,我想在類別存盤庫上使用相同的方法?
Service.xml 又名依賴注入器
<service id="wshop_product_service" class="WShop\Service\ProductService">
<argument type="service" id="product.repository"/>
<argument id="wshop_media_image_service" type="service"/>
<argument type="service" id="product_media.repository"/>
</service>
我是 OOP 的新手。請提供好的示例和代碼解釋。謝謝!
uj5u.com熱心網友回復:
如果我理解正確,您只希望第一個引數是可互換的,并且您的示例中的 3 個方法應該在抽象中實作。這是一個想法。
摘要:
abstract class AbstractEntityService
{
protected EntityRepository $repository;
public function __construct(EntityRepository $repository)
{
$this->repository = $repository;
}
public function create(array $data, ?Context $context = null): void
{
$context = $context ?? Context::createDefaultContext();
$this->repository->create([
$data
], $context);
}
public function update(array $data): void
{
$this->repository->update([$data], Context::createDefaultContext());
}
abstract public function getDataId(array $params): ?string;
protected function searchId(Criteria $criteria): ?string
{
return $this->repository->searchIds(
$criteria,
Context::createDefaultContext()
)->firstId();
}
}
您在建構式中獲取存盤庫并在抽象中實作有關通用存盤庫的所有通用方法。getDataId您要在擴展類中實作的方法,因為您對每個方法都使用了特定的標準(大概)。因此,您只需通過定義抽象簽名來強制擴展類中的實作。
您的服務等級:
class ProductService extends AbstractEntityService
{
private MediaImageService $mediaImageService;
private EntityRepository $productMediaRepository;
public function __construct(
EntityRepository $productRepository,
MediaImageService $mediaImageService,
EntityRepository $productMediaRepository
) {
parent::__construct($productRepository);
$this->mediaImageService = $mediaImageService;
$this->productMediaRepository = $productMediaRepository;
}
public function getDataId(array $params): ?string
{
if (!isset($params['productNumber'])) {
return null;
}
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('productNumber', $params['productNumber']));
return $this->searchId($criteria);
}
// your other methods using the injected services
}
在擴展類中,您僅將存盤庫傳遞給父建構式,因為其他注入的服務僅在此特定實體中使用。您getDataId在創建特定標準的位置實作并使用標準呼叫受保護的(因為它只能由擴展使用)searchId方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/523589.html
