JMSDiExtraBundle icon indicating copy to clipboard operation
JMSDiExtraBundle copied to clipboard

Can't define more than one service for a class

Open johnpancoast opened this issue 8 years ago • 10 comments

Using this bundle how can I define 2 services with different BarInterface implementations in this example?

class Foo
{
    public function __construct(BarInterface $bar) { … }
}

johnpancoast avatar Jan 15 '16 19:01 johnpancoast

can you explain how you try to add the service?

each implementation should look like this:

use JMS\DiExtraBundle\Annotation as DI;

/**
 * @DI\Service("impl1")
 */
class HighBar implements BarInterface
{}
use JMS\DiExtraBundle\Annotation as DI;

/**
 * @DI\Service("impl2")
 */
class LowBar implements BarInterface
{}

wodka avatar Feb 10 '16 22:02 wodka

Yea, that's how'd you'd define different implementations/services for BarInterface.

So now let's say I want to define 2 Foo services, one that accepts your HighBar service and another that gets LowBar. This is not too uncommon and I can with Symfony but I don't see a way (yet) to do it with this lib. It expects that the arguments you inject are for the one and only service you can create for the class.

Ideally we'd be able to create more than one service for a class. We'd just need a way to specify which service each argument is for.

johnpancoast avatar Feb 10 '16 23:02 johnpancoast

ah :)

this is still quite easy - http://jmsyst.com/bundles/JMSDiExtraBundle/master/usage#constructor-setter-injection

use JMS\DiExtraBundle\Annotation as DI;

class Controller
{
    private $impl1;
    private $impl2;

    /**
     * @DI\InjectParams({
     *     "impl1" = @DI\Inject("impl1"),
     *     "impl2" = @DI\Inject("impl2")
     * })
     */
    public function __construct($impl1, $impl2)
    {
        $this->impl1 = $impl1;
        $this->impl2 = $impl2;
    }
    // ... some actions
}

wodka avatar Feb 11 '16 13:02 wodka

I guess we can close this issue?

GuilhemN avatar Feb 11 '16 14:02 GuilhemN

You're just injecting two dependencies into one service. I'm saying I don't think you can define more than one service for a class.

In Symfony I can do this for example

services:
    bar_service_high:
        class: HighBar
    bar_service_low:
        class: LowBar

    foo_service_one:
        class: Foo
        arguments: [@bar_service_high]
    foo_service_two
        class: Foo
        arguments: [@bar_service_low]

I do not see a way to duplicate that behavior in this lib.

johnpancoast avatar Feb 11 '16 20:02 johnpancoast

@johnpancoast I see what you mean, this is actually not supported by this lib and we need to update the Metadata management to support it. Feel free to create a PR, I don't think i'll have the time to work on it.

GuilhemN avatar Feb 11 '16 20:02 GuilhemN

Cool! I'll try but I'm strapped for time too. I just wanted to make sure I wasn't missing some functionality I wasn't aware of.

johnpancoast avatar Feb 11 '16 20:02 johnpancoast

I just tried to implement it, we just need a nice way to inject data for each service :)

wodka avatar Feb 14 '16 18:02 wodka

Yup. A way to group them by name would work although i haven't looked at this code yet. I'll open it up today.

johnpancoast avatar Feb 14 '16 19:02 johnpancoast

@wodka, awesome. Looks like you're already on this. Let me know if I can help.

johnpancoast avatar Feb 16 '16 00:02 johnpancoast