-
Notifications
You must be signed in to change notification settings - Fork 2
Services
Services in SpiffyFramework are managed by the SpiffyInject component. SpiffyInject is SpiffyFramework's light-weight inversion of control container and is part of the foundation to the entire framework.
SpiffyInject also manage's package parameters. You can read more about this feature in the package documentation.
You can create services in the following ways:
- Setting using a string class name
- Setting the service directly
- Creating the service through a closure
- Using the array configuration
- Using an object that implements ServiceFactory
All services are set through the nject()
method regardless of which style you choose. Each style has it's own advantages and disadvantages. It's you to you to decide which is the best approach to take for your application.
By default, each package loads services using the services.php file in config/services.php
. Below is a simple example of the config/services.php
file.
// file: application/config/services.php
// 'service_name' => 'service_specification'
return [
'application.service' => 'Application\Service',
];
// file: application/config/services.php
return [
'application.service' => 'Application\Service',
];
Referencing application.service
would return an object that's an instance of Application\Service
.
// file: application/config/services.php
return [
'application.service' => new \Application\Service(),
];
Referencing application.service
would return an object that's an instance of Application\Service
but would create the service on every request. In general this method is not recommended because it's impossible to lazy-load the service.
// file: application/config/services.php
return [
'application.service' => function(\Spiffy\Inject\Injector $i) {
new \Application\Service($i->nvoke('foo'));
},
];
Using a closure allows you to inject additional dependencies before returning the service. A closure is good for rapid prototyping but is not recommended for production because closures can not be serialized. This means that you can not cache the package manager configuration.
// file:: application/src/MyServiceFactory;
namespace Application;
use Spiffy\Inject\Injector;
use Spiffy\Inject\ServiceFactory;
class MyServiceFactory implements ServiceFactory
{
public function createService(Injector $i)
{
return new Service($i->nvoke('foo'));
}
}
// file: application/config/services.php
return [
'application.service' => 'Application\MyServiceFactory'
];
Using a service factory is the first preferred method for creating services. By using a factory you can inject additional dependencies, cache the package manager configuration, and easily unit test your factory. A factory also provides you with the most flexibility for complex services.
// file: application/config/services.php
return [
'foo' => '\StdClass',
'application.service' => ['Application\Service', ['@foo']]
];
This is identical to the service factory above. An instance of Application\Service
is created and the 'foo' service is injected into the constructor. The array configuration is designed to provide you a rapid way to basic services with basic dependencies. This method is also able to be cached. This is the preferred method for creating services.
Read on for more information on the array configuration.
The array configuration allows constructor injection through the second array parameter passed to the service.
// file: application/config/services.php
return [
'foo' => '\StdClass',
'application.service' => ['Application\Service', ['@foo']]
];
The special '@' notation references another service for injection. In the example above Application\Service
would be constructor injected with the @foo
service which is an instance of StdClass
. Constructor injection should be used for immutable dependencies.
// file: application/config/services.php
return [
'foo' => '\StdClass',
'application.service' => ['Application\Service', [], ['setFoo' => '@foo']]
];
SpiffyInject allows for setter injection in addition to constructor injection through the third array parameter. The key should be the name of the method and the value should be the value to inject. The example above creates the Application\Service
and then injects the @foo
service using the setFoo()
method. Setter injection should be used for mutable dependencies.
© 2014 Kyle Spraggs