Description
I understand that everyone is busy release 3.0, but i want to make offer.
In a defined framework, i saw an interesting implementation dependencies for the controllers:
/**
* Home page
*
* @param array $get "GET"
* @param \Cms\Model\User|null $current_user "CURRENT_USER"
* @param \Cms\Model\Users $users "MODEL[Users]"
* @param \Cms\Model\Groups $groups "MODEL[Groups]"
* @param \Cms\Text\URLHelper $url "URL_HELPER"
*/
public function __index(
array $get,
User $current_user = null,
Users $users,
Groups $groups,
URLHelper $url
) {
// do something
}
It's not a very good framework, because all the application logic is in the controller, but i think it's a good idea to explicitly pass in the arguments of dependency.
We often turn to the dependencies of the controller in any place.
public function indexAction()
{
// lot of code
$repository = $em->getRepository('AcmeDemoBundle:User');
$user = $repository->findOneBy(['name' => 'foo']);
// lot of code
$param = $this->container->getParameter('my_parameter');
// lot of code
$service = $this->get('my_service');
// lot of code
}
This approach leads to the fact that all of the dependencies of the controller has to seek out in the code of methods. Those who use SensioLabsInsight familiar with the error and know what action method in the controller should contain as little code.
Symfony controller action method should not be too long
Yet, i believe that a clear description of the dependencies through annotations will be more convenient. How it might look:
/**
* Home page
*
* @Repository('AcmeDemoBundle:User', $repository)
* @Dependency('%my_parameter%', $param)
* @Dependency('my_service', $service)
*
* @param \Doctrine\Common\Persistence\ObjectRepository $repository
* @param \Acme\Bundle\DemoBundle\Service\MyService $service
* @param string $param
*/
public function indexAction(ObjectRepository $repository, MyService $service, $param)
{
// do something
}
Advantages
- An explicit description of the dependency list;
- Explicit description of the interfaces dependencies. Controllers depends not only on the services themselves, but also on their interface. We can replace the service implementation, but its interface should remain the same;
- You can declare a controller as a service and give him all the dependencies, but in this case, many dependencies are not used when executed the action methods. Dependencies are used only in specific methods, and not all over the controller.
- Announcing the controller as a service we lose autostart controllers. Each controller must be described separately in the configurations file with other services. If the controller appears method requires a new relationship, it is necessary to add to the configuration file and the constructor. Using annotated saves from writing extra code.
Disadvantages
- More annotations;
- Not all of the dependencies may be used. For example, the method of execution is interrupted before the is executed the service
my_service
; - All public services should have an interface in order to be able to replace the implementation using the existing interface.