The Harmoni Services offer two things: global access to pre-programmed classes, supplying authentication, file storage and others; and a way for you to make classes or objects you write available to all scopes of you program.
This chapter will concentrate on how Services are fetched and created, not on the individual supplied services themselves. For descriptions about those, see the next chapter.
The life-cycle of services includes the following steps:
- registration
- starting (instantiation/configuration)
- accessing
Use the Services::getService() method anywhere in your application to get a reference to the desired service. If the service of the name that you requested has not been registered or started, an error will be thrown.
$myService =& Services::getService("MyService");
To make some services even more accessible, one can write wrapper classes or functions to do common tasks with a specific service. For examples of these, take a look at the throwError and userError functions, and the debug class. These are all wrappers for the ErrorHandler, UserError and Debug services, respectively. A short example wrapper function:
function storeMyFile(&$file, $path, $filename) {
$storage =& Services::getService("Storage");
return $storage->store($file, $path, $filename);
}
Services methods involved in registration are
- Services::registerService(<a service name>, <a class name>)
- Services::registerObjectAsService(<a service name>, <an object>)
- Services::createServiceAlias(<a service name>, <an alias>)
The Services::registerObjectAsService() allows already instantiated objects to be used and access as services. However, they already are instantiated they cannont be started, only retrieved.
Aliases allow for one service to be referenced by multiple names as your codebase evolves. If we would like to start referring to the "MyService" as the "MySomethingManager" we could simply create an alias Services::createServiceAlias("MyService", "MySomethingManager") without breaking old code that uses the old name.
...
/*********************************************************
* Registration
*********************************************************/
// Include the class file
require_once(HARMONI."errorHandler/ErrorHandler.class.php");
// Register the Service
Services::registerService("ErrorHandler","ErrorHandler");
// Create an alias if desired
Services::createServiceAlias("ErrorHandler", "ErrorManager");
...
Creating new services is easy: Service::registerService("myService","className"). You can name your service anything, as long as another service doesn't have that name. The className argument is the class that should be instantiated. Any class you register should not take any constructor parameters and must implement the OsidManager interface so that it can be configured using assignConfiguration($configurationProperties) and given a context via assignOsidContext($osidContext). Then, anywhere you want, you can get the service named "MyService", and it will hand you the object of the class "className".
Sometimes it's useful to register a class that's already been instantiated as a service. This is especially useful if the class' constructor takes arguments. Here's the code:
$myObj =& new SomeClass($bla, $foo);
Services::registerObjectAsService("MyServiceTwo",$myObj);
Services should not take any constructor parameters and must implement the OsidManager interface so that they can be configured using assignConfiguration($configurationProperties) and given a context via assignOsidContext($osidContext).
...
/*********************************************************
* Registration
*********************************************************/
// Include the class file
require_once(HARMONI."errorHandler/ErrorHandler.class.php");
// Register the Service
Services::registerService("ErrorHandler","ErrorHandler");
// Create an alias if desired
Services::createServiceAlias("ErrorHandler", "ErrorManager");
...
/*********************************************************
* Starting
*********************************************************/
// Create an OsidContext object
// The ErrorHandler doesn't require any Context information, but the Harmoni object
// is useful for many classes, so we will just include it for example purposes.
require_once(OKI2."osid/OsidContext.php");
$context =& new OsidContext;
$context->assignContext('harmoni', $harmoni);
// Create a Properties object for configuration, empty as the ErrorHandler
// doesn't require any configuration.
require_once(HARMONI."oki2/shared/ConfigurationProperties.class.php");
$configuration =& new ConfigurationProperties;
// Start the Service
Services::startManagerAsService("ErrorHandler", $context, $configuration);
...
Replacing existing services is as easy as adding them. Two things need to be true for this to work though: 1) the service can't be started, 2) to avoid breaking a program, it must implement the same interface as the service to be replaced. Just call the registerService method with the same service name as the one you want to replace.