Shopware 6, kelas abstrak dan suntikan kebergantungan dalam Symfony
P粉680087550
P粉680087550 2024-01-09 08:44:57
0
1
504

Pada masa ini saya sedang membangunkan sambungan Shopware 6 berdasarkan Symfony. Apa yang saya tidak faham ialah cara melaksanakan kelas abstrak dan suntikan kebergantungan.

Jadi saya mahu dapat memfaktorkan semula kod dan menggunakan kaedah ini dengan kerap, tetapi dalam konteks lain (menggunakan repositori lain)

<?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();
 }
}

Seperti yang anda lihat, terdapat suntikan kebergantungan di dalam konstruk (repositori produk). Sekarang soalan saya ialah, bagaimana saya boleh membuat kelas abstrak, iaitu menyimpan kaedah ini, tetapi kelas anak akan "mengatasi" binaan induk dengan repositori yang diperlukan? Sebagai contoh, saya ingin menggunakan kaedah getDataId (kini dipanggil getExistingProductId, tetapi akan difaktorkan semula dan dinamakan semula dalam kelas abstrak) pada kaedah Repositori Produk, tetapi untuk kelas seterusnya saya mahu menggunakan yang sama pada Kategori Repositori Kaedah?

Service.xml juga dikenali sebagai penyuntik kebergantungan

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

Saya baru menggunakan OOP. Sila berikan contoh dan penjelasan kod yang baik. Terima kasih!

P粉680087550
P粉680087550

membalas semua(1)
P粉248602298

Jika saya faham dengan betul, anda hanya mahu parameter pertama boleh ditukar ganti, dan 3 kaedah dalam contoh harus dilaksanakan dalam abstraksi. Inilah idea.

Ringkasan:

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

Anda mendapat repositori dalam pembina dan melaksanakan semua kaedah biasa tentang repositori biasa dalam abstraksi. getDataId kaedah yang anda ingin laksanakan dalam kelas lanjutan anda kerana anda menggunakan syarat tertentu (mungkin) untuk setiap kaedah. Jadi anda hanya memaksa pelaksanaan dalam kelas lanjutan dengan menentukan tandatangan abstrak.

Tahap perkhidmatan anda:

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
}

Dalam kelas sambungan anda hanya menghantar repositori kepada pembina induk kerana perkhidmatan suntikan lain hanya digunakan dalam contoh khusus ini. Anda boleh melaksanakan getDataId 并使用该条件调用受保护的(因为它只能由扩展使用)searchId di mana anda membuat syarat tertentu dan memanggil kaedah yang dilindungi (kerana ia hanya boleh digunakan oleh sambungan) kaedah searchId dengan syarat tersebut.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan