On 9/23/10 2:48 AM, Bulat Shakirzyanov wrote:
Dear Symfony2 Developers,
After some time working with Symfony2 I am very grateful for the framework.
It has a very solid foundation and simple a joy to work with.
Thanks!
Everything uses the provided DIC component, which removes the pain of
framework setup and wiring of domain specific services.
However Controllers and Commands in Symfony2 are not quite like that.
They have access to the container instance, so they can get any service
that you might need, but it makes the api lie and controllers hardly
testable.
There is the web test case that let's you execute complete requests and
validate the outputs - sort of black box testing, but no support for
isolated unit tests.
In order to unit test something you either need to initialize the Kernel
or initialize local DIC and add all necessary services to it, passing
the DIC to your controller instance for testing.
Now since controllers are very lightweight classes, that don't need
anything but DIC to function, I propose to make them services and let
DIC handle the wiring.
You are not the first one to bring this topic on the table; but you are
the first to give an excellent example on how to test the expected
interaction instead of the outcomes by using mock objects. I now must
admit that this is something I want to support out of the box.
But first, you might have noticed that Symfony2 controllers do not need
to inherit from any base class. They can be POPO objects. The only thing
managed by Symfony2 is the injection of the Container if the controller
class implements ContainerAwareInterface (see the WebProfiler
controllers for an example). It means that everything provided by the
base Controller class is only about syntactic sugar, not about adding
features, which is a good thing IMO.
I don't want to force the usage of services as controllers as it means
that you need to add a new service in the configuration each time you
create a new controller. That's just too much work for beginners and too
many things to understand to get started. That should be an option
though for all the reasons you and some others mentioned.
We already have two ways to wire a controller and a route:
* "_controller: BlogBundle:Post:show": This uses the shortcut notation
and allows for a nice inheritance mechanism between the different root
namespaces (should be one explained first in the documentation).
* "_controller:
Bundle\BlogBundle\Controller\PostController::showAction": This uses a
class::method notation and it allows to reference any method of any
class as a controller (without any convention).
So, allowing services to be used as controllers is just a matter of
adding a third type:
* "_controller: controller.blog.post:showAction": This notation is
service_id:method_name. As you can see, it's very similar to the other
notations, but yet unique. So, we can pretty easily parse it and act on
it differently.
I have implemented that in the master branch:
http://github.com/fabpot/symfony/commit/2d80788e3aa7f406a14d00543d32ed1e81579bdb
As you can see, the patch is really trivial. Tell me what you think
about it and see if we need to enhance it somehow.
Fabien
--
If you want to report a vulnerability issue on symfony, please send it to
security at symfony-project.com
You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en