Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Repositories as a Services (Symfony) #67

Open
Kocal opened this issue Jul 10, 2019 · 0 comments

Comments

Projects
None yet
1 participant
@Kocal
Copy link

commented Jul 10, 2019

Hi, this feature request follows #65 (comment) and #65 (comment).

Since Symfony 4.0, it is possible to define Repositories as as Service by extending from ServiceEntityRepository like this:

<?php

namespace App\Repository\User;

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

/**
 * @method User|null find($id, $lockMode = null, $lockVersion = null)
 * @method User|null findOneBy(array $criteria, array $orderBy = null)
 * @method User[]    findAll()
 * @method User[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class UserRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, User::class);
    }
}

And we can accessing it directly from services constructor or constroller's actions with type hinting:

<?php

namespace App\Controller;

use App\Repository\User\UserRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class HomeController extends AbstractController
{
    /**
     * @Route("/", name="home")
     */
    public function index(UserRepository $userRepository)
    {
        $user = $userRepository->find(123);
        $user->getFooBar();
    }
}

But there are some issues.

If we use this phpstan extension, calling whatever method on $user that does not exist on App\Entity\User will not fails.

If we don't use it, $userRepository->find* methods will works correctly (due to @method annotations, but they are needed for PHPStorm too) and we will see the error Cannot call method getFooBar() on App\Entity\User|null.

As said in the issue, we can use /** @var App\Repository\UserRepository<App\Entity\User> */ to make phpstan works, but:

  • this is verbose, we have to add it everytime we inject a repository as service dependency
  • this is non sense, since the type is UserRepository, phpstan should be able to works with it

To make it work, this extension (or the Symfony extension?) should:

  • Find classes that extends from ServiceEntityRepository
  • Get the entity type from constructor 2nd parameter
  • And do some magic

In fact, I think it would be better if the repositories detection is part of Symfony extension. Since the Symfony extension can access the Symfony container, we can find services tagged with doctrine.repository_service and then use them:
Capture d’écran de 2019-07-10 06-37-23

What do you think?

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.