API Singleton method allowing type inference

This pattern improves over the current usage of singleton by allowing type inference.
This also better supports refactor, code usage detection, and auto-completion of classes.
This commit is contained in:
Damian Mooyman 2014-04-04 14:46:37 +13:00
parent 04e26d4a36
commit bf4e9eb044
3 changed files with 32 additions and 0 deletions

View File

@ -142,6 +142,27 @@ abstract class Object {
return Injector::inst()->createWithArgs($class, $args);
}
/**
* Creates a class instance by the "singleton" design pattern.
* It will always return the same instance for this class,
* which can be used for performance reasons and as a simple
* way to access instance methods which don't rely on instance
* data (e.g. the custom SilverStripe static handling).
*
* @param string $className Optional classname (if called on Object directly)
* @return static The singleton instance
*/
public static function singleton() {
$args = func_get_args();
// Singleton to create should be the calling class if not Object,
// otherwise the first parameter
$class = get_called_class();
if($class === 'Object') $class = array_shift($args);
return Injector::inst()->get($class);
}
private static $_cache_inst_args = array();
/**

View File

@ -36,6 +36,7 @@
* `SQLConditionalExpression/SQLQuery` `select()`, `limit()`, `orderby()`, `groupby()`, `having()`, `from()`, `leftjoin()`, `innerjoin()`, `where()` and `whereAny()` removed.
Use `set*()` and `add*()` methods instead.
* Template `<% control $MyList %>` syntax removed. Use `<% loop $MyList %>` instead.
* Object::singleton() method for better type-friendly singleton generation
### CMS

View File

@ -150,6 +150,16 @@ class ObjectTest extends SapphireTest {
$this->assertTrue($obj3_2 instanceof ObjectTest_CreateTest3);
}
/**
* Tests {@link Object::singleton()}
*/
public function testSingleton() {
$inst = Controller::singleton();
$this->assertInstanceOf('Controller', $inst);
$inst2 = Controller::singleton();
$this->assertSame($inst2, $inst);
}
public function testGetExtensions() {
$this->assertEquals(
Object::get_extensions('ObjectTest_ExtensionTest'),