Download the PHP package mindplay/boxy without Composer
On this page you can find all versions of the php package mindplay/boxy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download mindplay/boxy
More information about mindplay/boxy
Files in mindplay/boxy
Package boxy
Short Description Open, simple, type-hinted service container
License LGPL-3.0+
Informations about the package boxy
Boxy
Open, simple, type-hinted (and type-checked) dependency injection container for PHP 5.5 and up.
:warning: WARNING: this project is unmaintained and was superseded by Unbox.
Definitely inspired by Pimple but optimized for full IDE support, e.g. design-time and run-time type-checking, both on the provider and consumer side, in modern IDEs such as Php Storm :v:
Basic Usage
Create an instance of the Container:
Service objects can be inserted directly (eaglerly) into the container:
Or you can register factory functions to create services as late as possible:
Consumers can then ask for services by providing a function to be invoked:
You can also define optional dependencies, by using optional arguments:
In this example, if class Optional
has not been registered in the container, the
function will still be invoked, but will be passed a null
argument - be sure to
check for presence of optional arguments.
May be obvious, but note that, even if all the arguments are optional, and all the services/components are unavailable, the function will still be invoked.
Component Factory Usage
You can register factory functions to create components on demand:
Consumers can then ask for a new component instance the same way they ask for services:
In other words, the syntax is the same; whoever populates the container decides whether a given type should be registered as a service (same every time) or as a component (new instance every time.)
Named Services and Components
You can optionally name your service/component definitions - this is useful in cases where you have two distinct instances of the same class, or wish to provide two distinct implementations of an abstract class or interface. Every public API method has a named counterpart - for example, here we register two different cache components, both to a common interface:
Consumers then ask for these services by using argument names matching the names they were registered for - in this case:
The invoke()
method always tries to provide services/components with a matching
name first, but will fall back to a service/component definition matching only
the type - so, in a unit-testing scenario (where you don't have the calls to
registerNamed
above) you could mock both of the dependencies in the example
above, by registering a single mock cache:
The invoke()
method will now provide MockCache
instances for any CacheInterface
argument, regardless of whether the name matches.
The registerComponent()
method also has a registerNamedComponent()
counterpart,
and so on.
Configuring Services and Components
You can register additional configuration functions for a service or component:
Configuration functions will be executed as late as possible, e.g. the first
time you call invoke()
and ask for the service or component. (If a service
has already been initialized, the configuration function will execute immediately.)
Overriding Services
You can override a previously registered service creation function:
You can override component factory functions as well, at any time; note that overriding a service creation function is only possible until the service is initialized - an attempted override after initialization will cause an exception.
Packaged Service Providers
You can package service/component definitions for easy reuse by implementing
the Provider
interface:
Then register your custom provider with your container instance:
Note that providers get registered immediately - which means you should
still use registerService()
rather than insertService()
if you want
lazy initialization.
Consumer Interface
You can make components explicitly interoperable with the service
container by implementing the Consumer
interface, which is simply a
method that returns a function to invoke()
- this provides a means of
opening a class to dependency injection (also during tests, independently
of a Container
instance) without adding setters or making things public.
For example:
Now, assuming you have a Container
already configured to provide
instances of Cat
and Dog
, you can provide those dependencies by
passing a PetStore
to the provide()
method:
After this call, the function returned by the getInjector()
method
has been called, and the Cat
and Dog
dependencies have been provided.