Tomazi
Tomazi

Reputation: 847

Injecting services into Controller

I am learning Symfony2 and I am strugling with injecting services into my controller. I get this error:

Catchable Fatal Error: Argument 1 passed to Inter\DemoBundle\Controller\DataController::__construct() must be an instance of Inter\DemoBundle\Factory\ObjectFactory, none given, called in /home/tomazi/Dev/interface.test/app/cache/dev/classes.php on line 2138 and defined

I created a very basic structure Interface --> Factory --> Controller

My interface:

<?php
namespace Inter\DemoBundle\Interfaces;

interface ObjectInterface {

    public function create($testObject);

}

My Factory:

<?php
namespace Inter\DemoBundle\Factory;
use Inter\DemoBundle\Interfaces\ObjectInterface;

class ObjectFactory implements ObjectInterface{

    public function create($testObject)
    {
        $testObject = 'Hello World';
        return $testObject;
    }

}

My Controller:

<?php
namespace Inter\DemoBundle\Controller;
use Inter\DemoBundle\Factory\ObjectFactory;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DataController
{
    public $object;

    public function __construct(
        ObjectFactory $objectFactory
    ){
        $this->object = $objectFactory;
    }

    /**
     * @Route("/test")
     * @return ObjectFactory
     */
    public function test()
    {
        return $this->object;
    }

}

My Services.xml:

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <!--Factory Services-->
        <service id="inter.factory.object_factory"
                 class="Inter\DemoBundle\Factory\ObjectFactory">
        </service>

        <!--Controller Services-->
        <service id="inter.controller" class="Inter\DemoBundle\DataController">
            <argument type="service" id="inter.factory.object_factory" />
        </service>
    </services>

</container>

I am new to services judging by the error i am doing something wrong in services.xml but I am unable to find the mistake Can someone see what I am doing wrong..?

Regards

I think the Injection is now working but still get these new errors:

FileLoaderImportCircularReferenceException in FileLoader.php line 97:
Circular reference detected in 

"/home/tomazi/Dev/interface.test/app/config/routing_dev.yml" 

("/home/tomazi/Dev/interface.test/app/config/routing_dev.yml" > 

"/home/tomazi/Dev/interface.test/app/config/routing.yml" > 

"/home/tomazi/Dev/interface.test/src/Inter/DemoBundle/Controller/" > 

"/home/tomazi/Dev/interface.test/app/config/routing_dev.yml").

Upvotes: 2

Views: 1351

Answers (3)

Alessandro Lai
Alessandro Lai

Reputation: 2274

You could resolve this extending your controller from Symfony\Bundle\FrameworkBundle\Controller\Controller. It's a base Symfony class that extends ContainerAware, so it knows the container.

If you do that, you could simply resolve all your dipendeces like this:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class SomeController extends Controller
{
    public function someAction()
    {
        $someService = $this->get('some.service');
        ...
    }
}

Upvotes: 0

Durthar
Durthar

Reputation: 167

Two things:

  1. You need to pass a valid ObjectFactory object into your constructor. (your error says it isn't receiving one)
  2. You need to add "Action" to your method on your controller(*). Make sure your route is set properly, clear your cache, and try again.

*http://symfony.com/doc/current/cookbook/controller/service.html#referring-to-the-service

Upvotes: -2

b.b3rn4rd
b.b3rn4rd

Reputation: 8830

You need to modify your routing to refer to it as a service. For instance:

# app/config/routing.yml
hello:
    path:     /hello
    defaults: { _controller: inter.controller:indexAction }

If you are using annotations

/**
 * @Route("/test", service="inter.controller")
 */
public function test()
{
    return $this->object;
}

Upvotes: 3

Related Questions