WP App Container
DI Container and related tools to be used at website level.
Table of Contents
- What is and what is not
- Concepts overview
- Usage at website level
Usage at package level
- Contextual registration
- Package-dependant registration
- Providers workflow
<li> <a rel="nofollow noopener" target="_blank" href="#service-providers-id">Service providers ID</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#composing-the-container">Composing the container</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#simple-service-provider-example">Simple service provider example</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#service-provider-example-using-any-psr-11-container">Service provider example using any PSR-11 container</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#website-level-providers">Website-level providers</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#providers-package">Providers Package</a> </li> </ul>
- Advanced topics
- Crafted by Inpsyde
What is and what is not
This is a package aimed to solve dependency injection container, service providers, and application “bootstrapping”, at application, i.e. website, level.
The typical use case is when building a website for a client, for which we foresee to write several “packages”: library, plugins, and theme(s), that will be then “glued” together using Composer.
Thanks to this package will be possible to have a centralized dependency resolution, and a quite standardized and consistent structure for the backend of those packages.
Technically speaking, right now, there’s nothing that prevents the use at package level, however for several reasons, that is a no-goal of this package and no code will be added here to comply with that.
This package was not written to be “just a standard”, i.e. provide just the abstraction leaving the implementations to consumers, but instead had been written to be a ready-to-use implementation.
However, an underlying support for PSR-11 allows for very flexible usage.
This is the central class of the package. It is the place where “application bootstrapping” happen, where
Service Providers are registered, and it is very likely the only object that need to be used from the website “package” (that one that “glues” other packages/plugins/themes via Composer).
The package provides a single service provider interface (plus several abstract classes that partially implement it). The objects are used to “compose” the Container. Moreover, in this package implementation, service providers are (or better, could be) responsible to tell how to use the registered services. In WordPress world that very likely means to “add hooks”.
This is a “storage” that is capable of storing, and retrieve objects by an unique identifier. On retrieval (oftentimes just the first time they are retrieved), objects are “resolved”, meaning that any other object that is required for the target object to be constructed, will first recursively resolved in the container, and then injected in the target object before it is returned. The container implementation shipped here is an extension of Pimple, with added PSR-11 support, with the capability to act as a “proxy” to several other PSR-11 containers. Which means that Service Providers can “compose” the dependency three in the Container either by directly adding services factories to the underlying Pimple container or they can “append” to the main container a ready-made PSR-11 container.
As stated above, this package targets websites development, and something that is going to be required at website level is configuration. Working with WordPress configuration often means PHP constants, but when using Composer at website level, in combination with, for example, WP Starter it also also means environment variables. The package ships an
SiteConfig interface with an
EnvConfig implementation that does nothing in the regard of storing configuration, but offers a very flexible way to read configuration both from constants and env vars.
Container::config() method returns and instance of
Service providers job is to both add services in the container and add the hooks that make use of them, however in WordPress it often happens that services are required under a specific “context”. For example, a service provider responsible to register and enqueue assets for the front-end is not required in backoffice (dashboard), nor in AJAX or REST requests, and so on. Using the proper hooks to execute code is something that can be often addressed, but often not. E.g. distinguish a REST request is not very easy at an early hook, or there’s no function or constants that tell us when we are on a login page and so on. Moreover, even storing objects factories in the Container for things we are sure are not going to be used is waste of memory we can avoid. The
Context class of this package is a centralized service that provides info on the current request.
Container::context() method returns and…