对于服务定位器的实现,我们直接上代码:
1.注册服务,注册服务仅仅将定义数组存入defineMap中,不实例化对象。
public function registerService($serviceName, $serviceDefinition)
{
if (!empty($serviceDefinition)) {
if ($this->hasServiceInstance($serviceName)) {
unset($this->serviceMap[$serviceName]);
}
if (is_callable($serviceDefinition, true)) {
$this->defineMap[$serviceName] = $serviceDefinition;
} else if (is_object($serviceDefinition)) {
$this->defineMap[$serviceName] = $serviceDefinition;
} else if (is_array($serviceDefinition)){
if (isset($serviceDefinition['class'])) {
$this->defineMap[$serviceName] = $serviceDefinition;
} else {
throw new Exception('class key must be set in service definition array!');
}
} else {
throw new Exception('service definition must be callable,object or array!');
}
} else {
throw new Exception('service definition can not be empty!');
}
}
2.删除服务
public function removeService($serviceName)
{
if ($this->hasServiceInstance($serviceName)) {
unset($this->serviceMap[$serviceName]);
}
if ($this->hasServiceDefine($serviceName)) {
unset($this->defineMap[$serviceName]);
}
return;
}
3.解析并获取服务,在这一步才会根据defineMap中已经注册的定义来实例化相应的对象
public function parseService($serviceName)
{
$result = null;
if (isset($this->serviceMap[$serviceName])) {
$result = $this->serviceMap[$serviceName];
} else if (isset($this->defineMap[$serviceName])) {
$definition = $this->defineMap[$serviceName];
if (is_callable($definition, true)) {
$result = $definition;
} else if (is_object($definition)) {
$result = $definition;
} else {
$result = Tank::generateObject($definition);
}
$this->serviceMap[$serviceName] = $result;
} else {
throw new Exception('no this servcie!');
}
return $result;
}
4.提供以对象属性的方式获取服务的功能
public function __get($name)
{
if ($this->hasServiceDefine($name)) {
return $this->parseService();
} else {
return parent::__get($name);
}
}
5.其他辅助性功能
public function hasServiceDefine($serviceName)
{
return isset($this->defineMap[$serviceName]);
}
public function hasServiceInstance($serviceName)
{
return isset($this->serviceMap[$serviceName]);
}
public function __isset($name)
{
if ($this->hasServiceInstance($name)) {
return true;
} else {
return parent::__isset($name);
}
}
ok,今儿个先到这,欲知后事如何,且听下回分解……
github源码:https://github.com/2lovecode/tank