class Injector

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

Methods

__construct(array $config = null)

Create a new injector.

static Injector
inst(array $config = null)

If a user wants to use the injector as a static reference

static Injector
set_inst(Injector $instance)

Sets the default global injector instance.

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.

addAutoProperty(string $property, object $object)

Add an object that should be automatically set on managed objects

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

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)

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

registerService(stdClass $service, string $replace = null)

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

registerNamedService($name, $service) deprecated

Register a service with an explicit name

unregisterNamedObject(string $name)

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

unregisterAllObjects()

Clear out all objects that are managed by the injetor.

mixed
get(string $name, boolean $asSingleton = true, array $constructorArgs = null)

Get a named managed object

mixed
__get(string $name)

Magic method to return an item directly

mixed
create(string $name)

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

mixed
createWithArgs($name, $constructorArgs)

Creates an object with the supplied argument array

Details

at line 199
__construct(array $config = null)

Create a new injector.

Parameters

array $config Service configuration

at line 235
static Injector inst(array $config = null)

If a user wants to use the injector as a static reference

Parameters

array $config

Return Value

Injector

at line 248
static Injector set_inst(Injector $instance)

Sets the default global injector instance.

Parameters

Injector $instance

Return Value

Injector Reference to new active Injector instance

at line 262
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 276
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 294
setAutoScanProperties(boolean $val)

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

Parameters

boolean $val

at line 303
setObjectCreator(Factory $obj)

Sets the default factory to use for creating new objects.

Parameters

Factory $obj

at line 310
Factory getObjectCreator()

Return Value

Factory

at line 318
setConfigLocator(ServiceConfigurationLocator $configLocator)

Set the configuration locator

Parameters

ServiceConfigurationLocator $configLocator

at line 326
ServiceConfigurationLocator getConfigLocator()

Retrieve the configuration locator

at line 341
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 362
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

at line 372
load(array $config = array())

Load services using the passed in configuration for those services

Parameters

array $config

at line 458
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 496
convertServiceProperty(string $value)

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

Parameters

string $value

at line 600
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 729
string hasService($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 hasService for each depth of dotting

Parameters

$name

Return Value

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

at line 755
registerService(stdClass $service, string $replace = null)

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

Parameters

stdClass $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)

at line 771
registerNamedService($name, $service) deprecated

deprecated since 4.0

Register a service with an explicit name

Parameters

$name
$service

at line 782
unregisterNamedObject(string $name)

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

Parameters

string $name The name to unregister

at line 789
unregisterAllObjects()

Clear out all objects that are managed by the injetor.

at line 817
mixed get(string $name, boolean $asSingleton = true, array $constructorArgs = null)

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 specificied 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
boolean $asSingleton Whether to register the created object as a singleton if no other configuration is found
array $constructorArgs Optional set of arguments to pass as constructor arguments if this object is to be created from scratch (ie asSingleton = false)

Return Value

mixed the instance of the specified object

at line 879
mixed __get(string $name)

Magic method to return an item directly

Parameters

string $name The named object to retrieve

Return Value

mixed

at line 891
mixed create(string $name)

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

Additional parameters are passed through as

Parameters

string $name

Return Value

mixed A new instance of the specified object

at line 906
mixed createWithArgs($name, $constructorArgs)

Creates an object with the supplied argument array

Parameters

$name
$constructorArgs

Return Value

mixed