Это хороший способ сделать внедрение зависимостей в Symfony2?

Я зарегистрировал свой файл services.yml следующим образом:

services:
bb_shop.product_repository:
class: BB\ShopBundle\Entity\ProductRepository
factory_service: doctrine.orm.default_entity_manager
factory_method: getRepository
arguments: ['BBShopBundle:Product']
bb_shop.product_service:
class: BB\ShopBundle\Service\ProductService
arguments: [@bb_shop.product_repository]

Это мой класс репозитория:

class ProductRepository extends EntityRepository
{
public function saveProduct( $p)
{
$this->_em->persist($p);
$this->_em->flush();
}
}

Это мой класс обслуживания:

class ProductService {

protected   $productRepository;
public  function __construct(ProductRepository $R)
{
$this->productRepository =$R;
}
public function saveProduct( $p)
{
$this->productRepository->saveProduct($p);
}
}

И вот как я называю свой сервис в контроллере:

 $this->get('bb_shop.product_service')->saveProduct($product);

И все работают.
мои вопросы:
1- Можете ли вы объяснить мне, почему мне нужны эти 2 строки, даже если у меня есть EntityManager в EntityRepository (используется $ this -> _ em) ???

factory_service: doctrine.orm.default_entity_manager
factory_method: getRepository

2 — это хороший способ сделать инъекцию зависимости ???

1

Решение

  1. Вам нужны две строки, потому что хранилище не расширяет менеджер сущностей. Таким образом, в основном вы передаете persist / flush менеджеру сущностей. Это избавляет от необходимости выставлять менеджера сущностей для вашего сервиса. Вы могли бы ввести менеджера и позвонить по-прежнему / сбрасывать напрямую, но на самом деле зачем.

  2. Я использую твой подход все время. Так что это должно быть здорово. На данный момент я не столкнулся с серьезными проблемами.

Вы должны знать о побочном эффекте вызова saveProduct. В существующем состоянии ваш продукт сохранения сбрасывает менеджер сущностей, поэтому вы в конечном итоге сохраняете / обновляете любые сущности (не только конкретный продукт), которые могли измениться, поскольку все репозитории имеют одного и того же менеджера.

Это не было проблемой для меня. Просто что-то, о чем нужно знать. Если вы изменяете несколько продуктов в рамках одного запроса, возможно, вы захотите разбить их на части. Способ, которым все ваши изменения будут добавлены в базу данных за один раз.

class ProductRepository
{
public function persist($product) { return $this->_em->persist($product); }
public function flush($product) { return $this->_em->flush(); }

Еще одна причина такого подхода заключается в том, что он позволяет заменить репозиторий для тестирования. У меня есть репозитории на основе yaml, которые загружают некоторые объекты из файла yaml. В репозиториях представлены простые методы find / findAll, облегчающие написание тестовых функций. И кто знает, когда-нибудь вы решите переключиться на что-то другое, кроме Доктрины 2.

Я использую базовый класс репозитория:

use Doctrine\ORM\EntityRepository as BaseRepository;

class EntityRepository extends BaseRepository
{
// Create main entity
public function createEntity($params = array())
{
$entityName = $this->getEntityName();
return new $entityName($params);
}
// Allow null for id
public function find($id)
{
return $id ? parent::find($id) : null;
}
/* ==========================================================
* Persistence
*/
public function persist($entity) { return $this->getEntityManager()->persist($entity); }
public function refresh($entity) { return $this->getEntityManager()->refresh($entity); }
public function detach ($entity) { return $this->getEntityManager()->detach ($entity); }
public function remove ($entity) { return $this->getEntityManager()->remove ($entity); }
public function flush()          { return $this->getEntityManager()->flush();          }
public function clear()          { return $this->getEntityManager()->clear();

public function getReference($id) { return $this->getEntityManager()->getReference($this->getEntityName(),$id); }
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]