With our current system, it is difficult to define mappings and dependencies between certain systems. We require a system to handle not only the dynamic creation of objects, but also the definitions of what services we require.
Dependency Injection is a method to help decouple systems. Symfony provides a Dependency Injection component which we should use to handle our global objects, as well as define the mappings of which classes we want to use.
As a demonstration of how this API is used, this issue moves the $language_interface, $language_content, and $language_url global objects into this system everywhere they're used in core/includes/*, but defers to follow-up issues the cleanup of these global variables from the rest of core and the migration of other globals.
Review and get this patch RTBC... Once this patch is in, we can consider the following:
- Once the Kernel patch is in, bring the
drupal_container()Container instance in as a property of the Kernel object so that we have proper scope of all our Drupal objects
- Use an Event Dispatcher/module hook to have objects and classes register themselves as services
User interface changes
This brings in a ContainerBuilder singleton which allows us to handle the mappings between service classes and objects. There is a drupal_container() function which returns the desired service object. We will probably get rid of that once the Kernel patch goes in.
We considered using Pimple as a simpler alternative to Symfony's container, but decided on Symfony's because it has two important features not used in this initial patch but that we expect to need in followup work:
- Its configuration can be serialized (Pimple uses closures that cannot be serialized), which makes it possible to dump configuration to disk/database/whatever and reload easily without a massive rebuild process on each request.
- It has support for scoping to force regeneration of various items that depend on other items, which allows for easy context-switching within a request (e.g., for per-block subrequests or other code that wants to context switch). Pimple does not have any such built-in capability.
|PASSED: [[SimpleTest]]: [MySQL] 35,382 pass(es).|
|PASSED: [[SimpleTest]]: [MySQL] 35,355 pass(es).|
|PASSED: [[SimpleTest]]: [MySQL] 35,358 pass(es).|
|PASSED: [[SimpleTest]]: [MySQL] 35,345 pass(es).|
|FAILED: [[SimpleTest]]: [MySQL] 35,043 pass(es), 317 fail(s), and 375 exception(s).|