class Injector implements ContainerInterface

A simple injection manager that manages creating objects and injecting dependencies between them. It borrows quite a lot from ideas taken from Spring's configuration, but is adapted to the stateless PHP way of doing things.

In its simplest form, the dependency injector can be used as a mechanism to instantiate objects. Simply call

Injector::inst()->get('ClassName')

and a new instance of ClassName will be created and returned to you.

Classes can have specific configuration defined for them to indicate dependencies that should be injected. This takes the form of a static variable $dependencies defined in the class (or configuration), which indicates the name of a property that should be set.

eg

class MyController extends Controller {

 public $permissions;
 public $defaultText;

 static $dependencies = array(
     'defaultText'       => 'Override in configuration',
     'permissions'       => '%$PermissionService',
 );

}

will result in an object of type MyController having the defaultText property set to 'Override in configuration', and an object identified as PermissionService set into the property called 'permissions'. The %$ syntax tells the injector to look the provided name up as an item to be created by the Injector itself.

A key concept of the injector is whether to manage the object as

  • A pseudo-singleton, in that only one item will be created for a particular identifier (but the same class could be used for multiple identifiers)
  • A prototype, where the same configuration is used, but a new object is created each time
  • unmanaged, in which case a new object is created and injected, but no information about its state is managed.

Additional configuration of items managed by the injector can be done by providing configuration for the types, either by manually loading in an array describing the configuration, or by specifying the configuration for a type via SilverStripe's configuration mechanism.

Specify a configuration array of the format

array( array( 'id' => 'BeanId', // the name to be used if diff from the filename 'priority' => 1, // priority. If another bean is defined with the same ID, // but has a lower priority, it is NOT overridden 'class' => 'ClassName', // the name of the PHP class 'src' => '/path/to/file' // the location of the class 'type' => 'singleton|prototype' // if you want prototype object generation, set it as the // type // By default, singleton is assumed

     'factory' => 'FactoryService'                   // A factory service to use to create instances.
     'construct'     => array(                       // properties to set at construction
         'scalar',
         '%$BeanId',
     )
     'properties'    => array(
         'name' => 'value'                           // scalar value
         'name' => '%$BeanId',                       // a reference to another bean
         'name' => array(
             'scalar',
             '%$BeanId'
         )
     )
 )
 // alternatively
 'MyBean'        => array(
     'class'         => 'ClassName',
 )
 // or simply
 'OtherBean'     => 'SomeClass',

)

In addition to specifying the bindings directly in the configuration, you can simply create a publicly accessible property on the target class which will automatically be injected if the autoScanProperties option is set to true. This means a class defined as

class MyController extends Controller {

 private $permissionService;

 public setPermissionService($p) {
     $this->permissionService = $p;
 }

}

will have setPermissionService called if

  • Injector::inst()->setAutoScanProperties(true) is called and
  • A service named 'PermissionService' has been configured

Constants

SINGLETON

Specify a service type singleton

PROTOTYPE

Specif ya service type prototype

Methods

__construct(array $config = null)

Create a new injector.

static Injector
inst()

No description

static Injector
nest()

Make the newly active {@link Injector} be a copy of the current active {@link Injector} instance.

static Injector
unnest()

Change the active Injector back to the Injector instance the current active Injector object was copied from.

setAutoScanProperties(boolean $val)

Indicate whether we auto scan injected objects for properties to set.

setObjectCreator(Factory $obj)

Sets the default factory to use for creating new objects.

getObjectCreator()

No description

setConfigLocator(ServiceConfigurationLocator $configLocator)

Set the configuration locator

getConfigLocator()

Retrieve the configuration locator

setInjectMapping(string $class, string $property, string $toInject, string $injectVia = 'property')

Add in a specific mapping that should be catered for on a type.

$this
addAutoProperty(string $property, object $object)

Add an object that should be automatically set on managed objects

$this
load(array $config = array())

Load services using the passed in configuration for those services

updateSpec(string $id, string $property, mixed $value, boolean $append = true)

Update the configuration of an already defined service

array|mixed|string
convertServiceProperty(string $value)

Recursively convert a value into its proper representation with service references resolved to actual objects

inject(object $object, string $asType = null)

Inject $object with available objects from the service cache

string
hasService($name) deprecated

No description

boolean
has(string $name)

Does the given service exist?

string|null
getServiceName(string $name)

Does the given service exist, and if so, what's the stored name for it?

$this
registerService(object $service, string $replace = null)

Register a service object with an optional name to register it as the service for

$this
unregisterNamedObject(string $name)

Removes a named object from the cached list of objects managed by the inject

$this
unregisterObjects(array|string $types)

Clear out objects of one or more types that are managed by the injetor.

mixed
get(string $name, bool $asSingleton = true, array $constructorArgs = [])

Get a named managed object

mixed|object
getServiceSpec(string $name, bool $inherit = true)

Search for spec, lazy-loading in from config locator.

mixed
__get(string $name)

Magic method to return an item directly

mixed
create($name, $argument = null)

Similar to get() but always returns a new object of the given type

mixed
createWithArgs(string $name, array $constructorArgs)

Creates an object with the supplied argument array

Details

at line 214
__construct(array $config = null)

Create a new injector.

Parameters

array $config Service configuration

at line 249
static Injector inst()

Return Value

Injector

at line 264
static Injector nest()

Make the newly active {@link Injector} be a copy of the current active {@link Injector} instance.

You can then make changes to the injector with methods such as {@link Injector::inst()->registerService()} which will be discarded upon a subsequent call to {@link Injector::unnest()}

Return Value

Injector Reference to new active Injector instance

at line 278
static Injector unnest()

Change the active Injector back to the Injector instance the current active Injector object was copied from.

Return Value

Injector Reference to restored active Injector instance

at line 298
setAutoScanProperties(boolean $val)

Indicate whether we auto scan injected objects for properties to set.

Parameters

boolean $val

at line 308
setObjectCreator(Factory $obj)

Sets the default factory to use for creating new objects.

Parameters

Factory $obj

at line 316
Factory getObjectCreator()

Return Value

Factory

at line 325
setConfigLocator(ServiceConfigurationLocator $configLocator)

Set the configuration locator

Parameters

ServiceConfigurationLocator $configLocator

at line 334
ServiceConfigurationLocator getConfigLocator()

Retrieve the configuration locator

at line 350
setInjectMapping(string $class, string $property, string $toInject, string $injectVia = 'property')

Add in a specific mapping that should be catered for on a type.

This allows configuration of what should occur when an object of a particular type is injected, and what items should be injected for those properties / methods.

Parameters

string $class The class to set a mapping for
string $property The property to set the mapping for
string $toInject The registered type that will be injected
string $injectVia Whether to inject by setting a property or calling a setter

at line 373
$this addAutoProperty(string $property, object $object)

Add an object that should be automatically set on managed objects

This allows you to specify, for example, that EVERY managed object will be automatically inject with a log object by the following

$injector->addAutoProperty('log', new Logger());

Parameters

string $property the name of the property
object $object the object to be set

Return Value

$this

at line 385
$this load(array $config = array())

Load services using the passed in configuration for those services

Parameters

array $config

Return Value

$this

at line 469
updateSpec(string $id, string $property, mixed $value, boolean $append = true)

Update the configuration of an already defined service

Use this if you don't want to register a complete new config, just append to an existing configuration. Helpful to avoid overwriting someone else's changes

updateSpec('RequestProcessor', 'filters', '%$MyFilter')

Parameters

string $id The name of the service to update the definition for
string $property The name of the property to update.
mixed $value The value to set
boolean $append Whether to append (the default) when the property is an array

at line 510
array|mixed|string convertServiceProperty(string $value)

Recursively convert a value into its proper representation with service references resolved to actual objects

Parameters

string $value

Return Value

array|mixed|string

at line 639
inject(object $object, string $asType = null)

Inject $object with available objects from the service cache

Parameters

object $object The object to inject
string $asType The ID this item was loaded as. This is so that the property configuration for a type is referenced correctly in case $object is no longer the same type as the loaded config specification had it as.

at line 818
string hasService($name) deprecated

deprecated 4.0.0:5.0.0 Use Injector::has() instead

Parameters

$name

Return Value

string

at line 837
boolean has(string $name)

Does the given service exist?

We do a special check here for services that are using compound names. For example, we might want to say that a property should be injected with Log.File or Log.Memory, but have only registered a 'Log' service, we'll instead return that.

Will recursively call itself for each depth of dotting.

Parameters

string $name

Return Value

boolean

at line 854
string|null getServiceName(string $name)

Does the given service exist, and if so, what's the stored name for it?

We do a special check here for services that are using compound names. For example, we might want to say that a property should be injected with Log.File or Log.Memory, but have only registered a 'Log' service, we'll instead return that.

Will recursively call itself for each depth of dotting.

Parameters

string $name

Return Value

string|null The name of the service (as it might be different from the one passed in)

at line 879
$this registerService(object $service, string $replace = null)

Register a service object with an optional name to register it as the service for

Parameters

object $service The object to register
string $replace The name of the object to replace (if different to the class name of the object to register)

Return Value

$this

at line 898
$this unregisterNamedObject(string $name)

Removes a named object from the cached list of objects managed by the inject

Parameters

string $name The name to unregister

Return Value

$this

at line 911
$this unregisterObjects(array|string $types)

Clear out objects of one or more types that are managed by the injetor.

Parameters

array|string $types Base class of object (not service name) to remove

Return Value

$this

at line 953
mixed get(string $name, bool $asSingleton = true, array $constructorArgs = [])

Get a named managed object

Will first check to see if the item has been registered as a configured service/bean and return that if so.

Next, will check to see if there's any registered configuration for the given type and will then try and load that

Failing all of that, will just return a new instance of the specified object.

Parameters

string $name The name of the service to retrieve. If not a registered service, then a class of the given name is instantiated
bool $asSingleton If set to false a new instance will be returned. If true a singleton will be returned unless the spec is type=prototype'
array $constructorArgs Args to pass in to the constructor. Note: Ignored for singletons

Return Value

mixed Instance of the specified object

Exceptions

NotFoundExceptionInterface No entry was found for this identifier.

at line 1065
mixed|object getServiceSpec(string $name, bool $inherit = true)

Search for spec, lazy-loading in from config locator.

Falls back to parent service name if unloaded

Parameters

string $name
bool $inherit Set to true to inherit from parent service if . suffixed E.g. 'Psr/Log/LoggerInterface.custom' would fail over to 'Psr/Log/LoggerInterface'

Return Value

mixed|object

at line 1095
mixed __get(string $name)

Magic method to return an item directly

Parameters

string $name The named object to retrieve

Return Value

mixed

at line 1109
mixed create($name, $argument = null)

Similar to get() but always returns a new object of the given type

Additional parameters are passed through as

Parameters

$name
$argument

Return Value

mixed A new instance of the specified object

at line 1123
mixed createWithArgs(string $name, array $constructorArgs)

Creates an object with the supplied argument array

Parameters

string $name Name of the class to create an object of
array $constructorArgs Arguments to pass to the constructor

Return Value

mixed