FOSElasticaBundle icon indicating copy to clipboard operation
FOSElasticaBundle copied to clipboard

Make the finder services public, so they can be injected and TypeHinting

Open tacman opened this issue 5 years ago • 4 comments

The documentation on how to search assumes the container is available, which is not longer very common in Symfony 5 apps.

$finder = $this->container->get('fos_elastica.finder.app.user');

https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/doc/usage.md

If these were services were public, they could be injected via typehinting and variable naming.

Alternatively (or additionally), maybe there's a way to get the finder service from a service that is already public. If so, what is that? I'll update the documentation once I learn how to do it. Thanks.

tacman avatar Sep 10 '20 17:09 tacman

You don't have to make the service public. Just inject it via service configuration:

# services.yaml
services:

    App\Elastic\MyService:
        arguments:
            $finder: '@fos_elastica.finder.app.user'
namespace App\Elastic;

use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;

class MyService
{
    private PaginatedFinderInterface $finder;

    public function __construct(PaginatedFinderInterface $finder)
    {
        $this->finder = $finder;
    }
}

XWB avatar Sep 10 '20 21:09 XWB

Slightly less setup is to bind the parameters:

services:
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        bind:
            $finderWork: '@fos_elastica.finder.work'
            $finderParagraph: '@fos_elastica.finder.paragraph'

Then in the service or controller, use that variable

    /**
     * @Route("/search", name="search_dashboard")
     */
    public function search(Request $request, FinderInterface $finderParagraph, FinderInterface $finderWork, IndexManager $indexManager)
    {

BUT if they were public, these services could be used without configuring them in services.yaml, by using the camelcase version of the service name __construct(FinderInterface $fosElasticaFinderWork) I think. This is how monolog channels work, for example.

I think they should be public, though, because that's how they're intended to be used, and it greatly simplifies the documentation and DX.

tacman avatar Sep 11 '20 11:09 tacman

Ah, getting closer. Inject the RepositoryManager instead, which is already public.

That returns a Repository object, which has a protected $finder (a PaginatedFinder), and many of the methods.

Since the documentation shows how to get results from the $finder, not a Repository object, it seems like the finder object should be public.

Should I update the documentation and submit a PR?

tacman avatar Sep 11 '20 12:09 tacman

Just my two cents here. But we could probably register an automatic autowiring for finders and many other services.

I will propose a PR for that.

deguif avatar Sep 30 '20 16:09 deguif