Here is an almost typical use case when developing custom code for Drupal 8.
A third party module declare a controller with a method that you want to override because you need to change the logic and there is no practical way to do it in the module (could be a hook).
But this class implements ControllerBase with dependency injection, (and override most of the methods in ControllerBase, but this is an other subject).
A concrete example with module Message subscribe, included sub module message_subscribe_ui declare a controller SubscriptionController, it include a method getView()
which call and build a view for the administration pages.
Problem is the controller find a view based on a name with a flag:
And here is my concern, it's not good for me, in my case I am using PostreSQL and the views simply do not work! I need to override this code to add my own naming convention or custom code to build the page.
The controller declare method tab()
to create a tab for our pages and then call method getView()
to display the content.
My solution is to override in Drupal this method tab()
and alter getView()
, to do it I need to use RouteSubscriber to alter the class used by the controller as you can see in the Drupal documentation.
First step is to create a service using event_subscriber tag in a file my_module.services.yml
And replace the controller for this route
Now I can override and write my class with my new methods, but in this case I need to use a service not available in the original controller and to do so use the dependency injection with the constructor of the parent class.
There is not much documentation for this use case, here is my example without comments
As you can see it's simple, I use the original __construct()
and add my service. Then I add my service again in the create()
.