class Injector implements ContainerInterface (View source)

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(bool $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, bool $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

bool
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(string $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

__construct(array $config = null)

Create a new injector.

Parameters

array $config

Service configuration

static Injector inst()

Return Value

Injector

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

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

setAutoScanProperties(bool $val)

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

Parameters

bool $val

setObjectCreator(Factory $obj)

Sets the default factory to use for creating new objects.

Parameters

Factory $obj

Factory getObjectCreator()

Return Value

Factory

setConfigLocator(ServiceConfigurationLocator $configLocator)

Set the configuration locator

Parameters

ServiceConfigurationLocator $configLocator

ServiceConfigurationLocator 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 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

$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

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

Load services using the passed in configuration for those services

Parameters

array $config

Return Value

$this

updateSpec(string $id, string $property, mixed $value, bool $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

bool $append

Whether to append (the default) when the property is an array

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

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.

string hasService($name) deprecated

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

Parameters

$name

Return Value

string

bool 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

bool

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)

$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

$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

$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

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.

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

mixed __get(string $name)

Magic method to return an item directly

Parameters

string $name

The named object to retrieve

Return Value

mixed

mixed create(string $name, $argument = null)

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

Additional parameters are passed through as

Parameters

string $name
$argument

Return Value

mixed

A new instance of the specified object

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