I'll try to summarize the situation as I get it. Forgive the possible poor wording, and feel free to correct / edit :-)
Drupal has a DIC, and a drupal_container() functional wrapper to access it when it is not injected in the current scope.
The established best practice is to avoid using drupal_container() whenever possible, and instead;
- Inject the container in the client object that needs to access service objects from the container
The code in the client object then does
$service = $this->container->get('some.service');
That is using the container in a "service locator" style.
- Directly inject the service object into the client object (i.e fetching the service from the container *outside* the client object, the client object is not aware there's such a thing as a centralizing container object)
That is using the container in a "real dependency injection" style, and, if I get things right, is preferred when possible.
More and more, and rightly so, patches that add drupal_container() calls within OO methods raise "we should make that injectable" comments.
Problem : our main mechanisms for creating objects (the Plugin API & the Entity API) do not allow either of the above, because they use generic factories that are not container aware. Right now, I need something from the DIC in an object that's either an entity (say, a config entity) or a plugin implementation, I have no other way than calling drupal_container().
I'll focus on the Plugin API here.
Possible approaches :
1) Add a ContainerAwareFactory, that receives the container from the plugin manager (no problem here, the plugin manager, being exposed in the DIC, can receive the DIC itself) and passes it to instantiated plugin instances.
This only allows plugin classes to use the container in a "service locator" way. No direct injection of the actual objects.
2) Allow real dependency injection in plugin classes ? Note that the plugin manager or factory cannot predict which DIC entries a specific plugin implementation class will need.
It seems this means having a way for plugin classes to expose which DIC entries they need - in their metadata ? in a static method ?
Then the ContainerAwareFactory can read this info, fetch the corresponding objects from the DIC, and pass them to the plugin constructor.
3) other proposals ?
|PASSED: [[SimpleTest]]: [MySQL] 55,607 pass(es).|
|FAILED: [[SimpleTest]]: [MySQL] 55,914 pass(es), 74 fail(s), and 102 exception(s).|
|FAILED: [[SimpleTest]]: [MySQL] Setup environment: Test cancelled by admin prior to completion.|
|PASSED: [[SimpleTest]]: [MySQL] 54,459 pass(es).|