Merge pull request #17755 from owncloud/alias-container-alive

Add registerAlias method to shortcut interface registration #17714
This commit is contained in:
Thomas Müller 2015-07-24 13:11:32 +02:00
commit 1f8ee61006
4 changed files with 68 additions and 51 deletions

View File

@ -39,8 +39,6 @@ use OC\AppFramework\Middleware\Security\SecurityMiddleware;
use OC\AppFramework\Middleware\Security\CORSMiddleware; use OC\AppFramework\Middleware\Security\CORSMiddleware;
use OC\AppFramework\Middleware\SessionMiddleware; use OC\AppFramework\Middleware\SessionMiddleware;
use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\IApi; use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer; use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\Middleware; use OCP\AppFramework\Middleware;
@ -63,15 +61,9 @@ class DIContainer extends SimpleContainer implements IAppContainer {
$this['urlParams'] = $urlParams; $this['urlParams'] = $urlParams;
// aliases // aliases
$this->registerService('appName', function($c) { $this->registerAlias('appName', 'AppName');
return $c->query('AppName'); $this->registerAlias('webRoot', 'WebRoot');
}); $this->registerAlias('userId', 'UserId');
$this->registerService('webRoot', function($c) {
return $c->query('WebRoot');
});
$this->registerService('userId', function($c) {
return $c->query('UserId');
});
/** /**
* Core services * Core services
@ -156,9 +148,8 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getJobList(); return $this->getServer()->getJobList();
}); });
$this->registerService('OCP\\AppFramework\\Utility\\IControllerMethodReflector', function($c) { $this->registerAlias('OCP\\AppFramework\\Utility\\IControllerMethodReflector', 'OC\AppFramework\Utility\ControllerMethodReflector');
return $c->query('ControllerMethodReflector'); $this->registerAlias('ControllerMethodReflector', 'OCP\\AppFramework\\Utility\\IControllerMethodReflector');
});
$this->registerService('OCP\\INavigationManager', function($c) { $this->registerService('OCP\\INavigationManager', function($c) {
return $this->getServer()->getNavigationManager(); return $this->getServer()->getNavigationManager();
@ -168,9 +159,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getPreviewManager(); return $this->getServer()->getPreviewManager();
}); });
$this->registerService('OCP\\IRequest', function($c) { $this->registerService('OCP\\IRequest', function () {
return $c->query('Request'); return $this->getServer()->getRequest();
}); });
$this->registerAlias('Request', 'OCP\\IRequest');
$this->registerService('OCP\\ITagManager', function($c) { $this->registerService('OCP\\ITagManager', function($c) {
return $this->getServer()->getTagManager(); return $this->getServer()->getTagManager();
@ -180,9 +172,9 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getTempManager(); return $this->getServer()->getTempManager();
}); });
$this->registerService('OCP\\AppFramework\\Utility\\ITimeFactory', function($c) { $this->registerAlias('OCP\\AppFramework\\Utility\\ITimeFactory', 'OC\AppFramework\Utility\TimeFactory');
return $c->query('TimeFactory'); $this->registerAlias('TimeFactory', 'OCP\\AppFramework\\Utility\\ITimeFactory');
});
$this->registerService('OCP\\Route\\IRouter', function($c) { $this->registerService('OCP\\Route\\IRouter', function($c) {
return $this->getServer()->getRouter(); return $this->getServer()->getRouter();
@ -245,14 +237,6 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return new API($c['AppName']); return new API($c['AppName']);
}); });
$this->registerService('Request', function($c) {
/** @var $c SimpleContainer */
/** @var $server SimpleContainer */
$server = $c->query('ServerContainer');
/** @var $server IServerContainer */
return $server->getRequest();
});
$this->registerService('Protocol', function($c){ $this->registerService('Protocol', function($c){
if(isset($_SERVER['SERVER_PROTOCOL'])) { if(isset($_SERVER['SERVER_PROTOCOL'])) {
return new Http($_SERVER, $_SERVER['SERVER_PROTOCOL']); return new Http($_SERVER, $_SERVER['SERVER_PROTOCOL']);
@ -318,18 +302,6 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $dispatcher; return $dispatcher;
}); });
/**
* Utilities
*/
$this->registerService('TimeFactory', function($c){
return new TimeFactory();
});
$this->registerService('ControllerMethodReflector', function($c) {
return new ControllerMethodReflector();
});
} }

View File

@ -26,21 +26,28 @@
namespace OC\AppFramework\Utility; namespace OC\AppFramework\Utility;
use \OCP\AppFramework\QueryException; use ReflectionClass;
use ReflectionException;
use Closure;
use Pimple\Container;
use OCP\AppFramework\QueryException;
use OCP\IContainer;
/** /**
* Class SimpleContainer * Class SimpleContainer
* *
* SimpleContainer is a simple implementation of IContainer on basis of \Pimple * SimpleContainer is a simple implementation of IContainer on basis of Pimple
*/ */
class SimpleContainer extends \Pimple\Container implements \OCP\IContainer { class SimpleContainer extends Container implements IContainer {
/** /**
* @param \ReflectionClass $class the class to instantiate * @param ReflectionClass $class the class to instantiate
* @return \stdClass the created class * @return stdClass the created class
*/ */
private function buildClass(\ReflectionClass $class) { private function buildClass(ReflectionClass $class) {
$constructor = $class->getConstructor(); $constructor = $class->getConstructor();
if ($constructor === null) { if ($constructor === null) {
return $class->newInstance(); return $class->newInstance();
@ -67,20 +74,20 @@ class SimpleContainer extends \Pimple\Container implements \OCP\IContainer {
* If a parameter is not registered in the container try to instantiate it * If a parameter is not registered in the container try to instantiate it
* by using reflection to find out how to build the class * by using reflection to find out how to build the class
* @param string $name the class name to resolve * @param string $name the class name to resolve
* @return \stdClass * @return stdClass
* @throws QueryException if the class could not be found or instantiated * @throws QueryException if the class could not be found or instantiated
*/ */
private function resolve($name) { private function resolve($name) {
$baseMsg = 'Could not resolve ' . $name . '!'; $baseMsg = 'Could not resolve ' . $name . '!';
try { try {
$class = new \ReflectionClass($name); $class = new ReflectionClass($name);
if ($class->isInstantiable()) { if ($class->isInstantiable()) {
return $this->buildClass($class); return $this->buildClass($class);
} else { } else {
throw new QueryException($baseMsg . throw new QueryException($baseMsg .
' Class can not be instantiated'); ' Class can not be instantiated');
} }
} catch(\ReflectionException $e) { } catch(ReflectionException $e) {
throw new QueryException($baseMsg . ' ' . $e->getMessage()); throw new QueryException($baseMsg . ' ' . $e->getMessage());
} }
} }
@ -117,10 +124,10 @@ class SimpleContainer extends \Pimple\Container implements \OCP\IContainer {
* Created instance will be cached in case $shared is true. * Created instance will be cached in case $shared is true.
* *
* @param string $name name of the service to register another backend for * @param string $name name of the service to register another backend for
* @param \Closure $closure the closure to be called on service creation * @param Closure $closure the closure to be called on service creation
* @param bool $shared * @param bool $shared
*/ */
public function registerService($name, \Closure $closure, $shared = true) { public function registerService($name, Closure $closure, $shared = true) {
if (isset($this[$name])) { if (isset($this[$name])) {
unset($this[$name]); unset($this[$name]);
} }
@ -131,5 +138,17 @@ class SimpleContainer extends \Pimple\Container implements \OCP\IContainer {
} }
} }
/**
* Shortcut for returning a service from a service under a different key,
* e.g. to tell the container to return a class when queried for an
* interface
* @param string $alias the alias that should be registered
* @param string $target the target that should be resolved instead
*/
public function registerAlias($alias, $target) {
$this->registerService($alias, function (IContainer $container) use ($target) {
return $container->query($target);
});
}
} }

View File

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
use Closure;
/** /**
* Class IContainer * Class IContainer
* *
@ -72,5 +75,15 @@ interface IContainer {
* @return void * @return void
* @since 6.0.0 * @since 6.0.0
*/ */
public function registerService($name, \Closure $closure, $shared = true); public function registerService($name, Closure $closure, $shared = true);
/**
* Shortcut for returning a service from a service under a different key,
* e.g. to tell the container to return a class when queried for an
* interface
* @param string $alias the alias that should be registered
* @param string $target the target that should be resolved instead
* @since 8.2.0
*/
public function registerAlias($alias, $target);
} }

View File

@ -153,6 +153,19 @@ class SimpleContainerTest extends \Test\TestCase {
$this->assertEquals('abc', $object->test); $this->assertEquals('abc', $object->test);
} }
public function testRegisterAliasParamter() {
$this->container->registerParameter('test', 'abc');
$this->container->registerAlias('test1', 'test');
$this->assertEquals('abc', $this->container->query('test1'));
}
public function testRegisterAliasService() {
$this->container->registerService('test', function() {
return 'abc';
});
$this->container->registerAlias('test1', 'test');
$this->assertEquals('abc', $this->container->query('test1'));
}
/** /**
* @expectedException \OCP\AppFramework\QueryException * @expectedException \OCP\AppFramework\QueryException