Mwjames has uploaded a new change for review.
https://gerrit.wikimedia.org/r/80070
Change subject: Move DependencyBuilder into \dic\, improve readability and add
README
......................................................................
Move DependencyBuilder into \dic\, improve readability and add README
* Split-up files for better readability
* Clean-up some temp code after the first merge
Change-Id: I1cd202b322acd66562f640ef91932df7a272e63b
---
M SemanticMediaWiki.classes.php
M SemanticMediaWiki.hooks.php
D includes/DependencyContainer.php
D includes/DependencyInjector.php
A includes/dic/BaseDependencyContainer.php
A includes/dic/DependencyBuilder.php
A includes/dic/DependencyContainer.php
A includes/dic/DependencyInjector.php
A includes/dic/DependencyRequestor.php
A includes/dic/EmptyDependencyContainer.php
A includes/dic/README.mediawiki
A includes/dic/SharedDependencyContainer.php
R includes/dic/SimpleDependencyBuilder.php
M includes/hooks/ArticlePurge.php
A includes/hooks/FunctionHookRegistry.php
M includes/hooks/HooksLoader.php
A includes/hooks/InjectableHook.php
R tests/phpunit/includes/dic/DependencyInjectorTest.php
R tests/phpunit/includes/dic/SharedDependencyContainerTest.php
R tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
A tests/phpunit/includes/hooks/FunctionHookRegistryTest.php
21 files changed, 770 insertions(+), 432 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticMediaWiki
refs/changes/70/80070/1
diff --git a/SemanticMediaWiki.classes.php b/SemanticMediaWiki.classes.php
index d836d93..962aa9d 100644
--- a/SemanticMediaWiki.classes.php
+++ b/SemanticMediaWiki.classes.php
@@ -76,21 +76,21 @@
'SMW\DispatchableSubject' =>
'includes/ObservableSubjectDispatcher.php',
'SMW\ObservableSubjectDispatcher' =>
'includes/ObservableSubjectDispatcher.php',
- // Dependency Injection Builder
- 'SMW\DependencyFactory' =>
'includes/DependencyBuilder.php',
- 'SMW\DependencyBuilder' =>
'includes/DependencyBuilder.php',
- 'SMW\SimpleDependencyBuilder' =>
'includes/DependencyBuilder.php',
+ // Dependency Builder
+ 'SMW\DependencyFactory' =>
'includes/dic/DependencyBuilder.php',
+ 'SMW\DependencyBuilder' =>
'includes/dic/DependencyBuilder.php',
+ 'SMW\SimpleDependencyBuilder' =>
'includes/dic/SimpleDependencyBuilder.php',
- // Dependency Injection Container
- 'SMW\DependencyObject' =>
'includes/DependencyContainer.php',
- 'SMW\DependencyContainer' =>
'includes/DependencyContainer.php',
- 'SMW\DependencyContainerBase' =>
'includes/DependencyContainer.php',
- 'SMW\EmptyDependencyContainer' =>
'includes/DependencyContainer.php',
- 'SMW\CommonDependencyContainer' =>
'includes/DependencyContainer.php',
+ // Dependency Container
+ 'SMW\DependencyObject' =>
'includes/dic/DependencyContainer.php',
+ 'SMW\DependencyContainer' =>
'includes/dic/DependencyContainer.php',
+ 'SMW\BaseDependencyContainer' =>
'includes/dic/BaseDependencyContainer.php',
+ 'SMW\EmptyDependencyContainer' =>
'includes/dic/EmptyDependencyContainer.php',
+ 'SMW\SharedDependencyContainer' =>
'includes/dic/SharedDependencyContainer.php',
- // Dependency Injection Helper
- 'SMW\DependencyRequestor' =>
'includes/DependencyInjector.php',
- 'SMW\DependencyInjector' =>
'includes/DependencyInjector.php',
+ // Dependency Injector
+ 'SMW\DependencyRequestor' =>
'includes/dic/DependencyRequestor.php',
+ 'SMW\DependencyInjector' =>
'includes/dic/DependencyInjector.php',
'SMW\Cacheable' => 'includes/Cacheable.php',
'SMW\Configurable' => 'includes/Configurable.php',
@@ -108,6 +108,8 @@
'SMW\LinksUpdateConstructed' =>
'includes/hooks/LinksUpdateConstructed.php',
'SMW\BeforePageDisplay' =>
'includes/hooks/BeforePageDisplay.php',
'SMW\ArticlePurge' => 'includes/hooks/ArticlePurge.php',
+ 'SMW\InjectableHook' => 'includes/hooks/InjectableHook.php',
+ 'SMW\FunctionHookRegistry' =>
'includes/hooks/FunctionHookRegistry.php',
// Formatters
'SMW\ArrayFormatter' =>
'includes/formatters/ArrayFormatter.php',
diff --git a/SemanticMediaWiki.hooks.php b/SemanticMediaWiki.hooks.php
index d477813..2838443 100644
--- a/SemanticMediaWiki.hooks.php
+++ b/SemanticMediaWiki.hooks.php
@@ -572,7 +572,7 @@
* @return true
*/
public static function onArticlePurge( &$wikiPage ) {
- return \SMW\HooksLoader::prepare( new \SMW\ArticlePurge(
$wikiPage ) )->process();
+ return \SMW\FunctionHookRegistry::register( new
\SMW\ArticlePurge( $wikiPage ) )->process();
}
/**
diff --git a/includes/DependencyContainer.php b/includes/DependencyContainer.php
deleted file mode 100644
index fffb941..0000000
--- a/includes/DependencyContainer.php
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-
-namespace SMW;
-
-/**
- * Provides objects for dependcy injection
- *
- * @file
- *
- * @license GNU GPL v2+
- * @since 1.9
- *
- * @author mwjames
- */
-
-/**
- * Interface specifying a dependency object
- *
- * @ingroup DependencyContainer
- */
-interface DependencyObject {
-
- /**
- * Register a dependency object
- *
- * @since 1.9
- */
- public function registerObject( $objectName, $objectSignature );
-
-}
-
-/**
- * Interface specifying a dependency container
- *
- * @ingroup DependencyContainer
- */
-interface DependencyContainer extends DependencyObject, Accessible,
Changeable, Combinable {}
-
-/**
- * Provides a DependencyContainer base class
- *
- * @ingroup DependencyContainer
- */
-abstract class DependencyContainerBase extends ObjectStorage implements
DependencyContainer {
-
- /**
- * @see ObjectStorage::contains
- *
- * @since 1.9
- */
- public function has( $key ) {
- return $this->contains( $key );
- }
-
- /**
- * @see ObjectStorage::lookup
- *
- * @since 1.9
- */
- public function get( $key ) {
- return $this->lookup( $key );
- }
-
- /**
- * @see ObjectStorage::attach
- *
- * @since 1.9
- */
- public function set( $key, $value ) {
- return $this->attach( $key, $value );
- }
-
- /**
- * @see ObjectStorage::detach
- *
- * @since 1.9
- */
- public function remove( $key ) {
- return $this->detach( $key );
- }
-
- /**
- * Returns storage array
- *
- * @since 1.9
- *
- * @return array
- */
- public function toArray() {
- return $this->storage;
- }
-
- /**
- * Merges elements of one or more arrays together
- *
- * @since 1.9
- *
- * @param array $mergeable
- *
- * @return HashArray
- */
- public function merge( array $mergeable ) {
- $this->storage = array_merge( $this->storage, $mergeable );
- }
-
- /**
- * Register an object via magic method __set
- *
- * @par Example:
- * @code
- * $container = new EmptyDependencyContainer()
- *
- * // Eager loading (do everything when asked)
- * $container->title = new Title() or
- *
- * // Lazy loading (only do an instanitation when required)
- * $container->diWikiPage = function ( DependencyBuilder $builder ) {
- * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' )
);
- * } );
- * @endcode
- *
- * @since 1.9
- *
- * @param string $key
- * @param mixed $value
- */
- public function __set( $objectName, $objectSignature ) {
- $this->set( $objectName, $objectSignature );
- }
-
- /**
- * Register an object
- *
- * @par Example:
- * @code
- * $container = new EmptyDependencyContainer()
- *
- * // Eager loading (do everything when asked)
- * $container->registerObject( 'Title', new Title() ) or
- *
- * // Lazy loading (only do an instanitation when required)
- * $container->registerObject( 'DIWikiPage', function (
DependencyBuilder $builder ) {
- * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' )
);
- * } );
- * @endcode
- *
- * @since 1.9
- *
- * @param string $objectName
- * @param mixed $signature
- */
- public function registerObject( $objectName, $objectSignature ) {
- $this->set( $objectName, $objectSignature );
- }
-
-}
-
-/**
- * Implementation of an empty DependencyContainer entity
- *
- * @ingroup DependencyContainer
- */
-class EmptyDependencyContainer extends DependencyContainerBase {}
-
-/**
- * Implementation of a general purpose objects DependencyContainer
- *
- * @ingroup DependencyContainer
- */
-class CommonDependencyContainer extends DependencyContainerBase {
-
- /**
- * @since 1.9
- */
- public function __construct() {
- $this->load();
- }
-
- /**
- * Load pre-existing object definitions
- *
- * @since 1.9
- */
- public function load() {
-
- $this->registerObject( 'Settings', function () {
- return Settings::newFromGlobals();
- } );
-
- $this->registerObject( 'Store', function ( DependencyBuilder
$builder ) {
- return StoreFactory::getStore( $builder->newObject(
'Settings' )->get( 'smwgDefaultStore' ) );
- } );
-
- $this->registerObject( 'CacheHandler', function (
DependencyBuilder $builder ) {
- return CacheHandler::newFromId( $builder->newObject(
'Settings' )->get( 'smwgCacheType' ) );
- } );
-
- $this->registerObject( 'ParserData', function (
DependencyBuilder $builder ) {
- return new ParserData(
- $builder->getArgument( 'Title' ),
- $builder->getArgument( 'ParserOutput' )
- );
- } );
-
- // $this->set( 'FactboxPresenter', function ( DependencyBuilder
$builder ) {
- // $outputPage = $builder->getArgument( 'OutputPage' );
- // return new FactboxPresenter( $outputPage,
$builder->newObject( 'Settings' ) );
- // } );
-
- // $this->set( 'Factbox', function ( DependencyBuilder $builder
) {
- // return new Factbox(
- // $builder->newObject( 'Store' ),
- // $builder->getArgument( 'SMW\ParserData' ),
- // $builder->getArgument( 'SMW\Settings' ),
- // $builder->getArgument( 'RequestContext' )
- // );
- // } );
-
- }
-
-}
diff --git a/includes/DependencyInjector.php b/includes/DependencyInjector.php
deleted file mode 100644
index 311068c..0000000
--- a/includes/DependencyInjector.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-namespace SMW;
-
-use InvalidArgumentException;
-use OutOfBoundsException;
-
-/**
- * Interface specifying access to a DependencyBuilder
- *
- * @file
- *
- * @license GNU GPL v2+
- * @since 1.9
- *
- * @author mwjames
- */
-
-/**
- * Specifies methods to access a DependencyBuilder within a client that
requests
- * dependency injection
- *
- * @ingroup DependencyRequestor
- */
-interface DependencyRequestor {
-
- /**
- * Sets DependencyBuilder
- *
- * @since 1.9
- */
- public function setDependencyBuilder( DependencyBuilder $builder );
-
- /**
- * Sets DependencyBuilder
- *
- * @since 1.9
- */
- public function getDependencyBuilder();
-
-}
-
-/**
- * Abstract class that implements the DependencyRequestor to enable convenience
- * access to an injected DependencyBuilder
- *
- * @par Example:
- * @code
- * class ArticlePurge extends DependencyInjector { ... }
- * $articlePurge = new ArticlePurge( ... )
- * $articlePurge->setDependencyBuilder( new SimpleDependencyBuilder(
- * new CommonDependencyContainer()
- * ) );
- * $articlePurge->getDependencyBuilder()->newObject( 'Settings' );
- * @endcode
- *
- * @since 1.9
- *
- * @ingroup DependencyRequestor
- */
-abstract class DependencyInjector implements DependencyRequestor {
-
- /** @var DependencyBuilder */
- protected $dependencyBuilder;
-
- /**
- * Injects a DependencyBuilder object
- *
- * @since 1.9
- */
- public function setDependencyBuilder( DependencyBuilder $builder ) {
- $this->dependencyBuilder = $builder;
- }
-
- /**
- * Returns injected DependencyBuilder object
- *
- * @since 1.9
- */
- public function getDependencyBuilder() {
- return $this->dependencyBuilder;
- }
-}
diff --git a/includes/dic/BaseDependencyContainer.php
b/includes/dic/BaseDependencyContainer.php
new file mode 100644
index 0000000..3ac6c2c
--- /dev/null
+++ b/includes/dic/BaseDependencyContainer.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Provides a DependencyContainer base class
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Implements the DependencyContainer interface and is responsible for handling
+ * object storage, and retrieval of object definitions
+ *
+ * @ingroup DependencyContainer
+ */
+abstract class BaseDependencyContainer extends ObjectStorage implements
DependencyContainer {
+
+ /**
+ * @see ObjectStorage::contains
+ *
+ * @since 1.9
+ */
+ public function has( $key ) {
+ return $this->contains( $key );
+ }
+
+ /**
+ * @see ObjectStorage::lookup
+ *
+ * @since 1.9
+ */
+ public function get( $key ) {
+ return $this->lookup( $key );
+ }
+
+ /**
+ * @see ObjectStorage::attach
+ *
+ * @since 1.9
+ */
+ public function set( $key, $value ) {
+ return $this->attach( $key, $value );
+ }
+
+ /**
+ * @see ObjectStorage::detach
+ *
+ * @since 1.9
+ */
+ public function remove( $key ) {
+ return $this->detach( $key );
+ }
+
+ /**
+ * Returns storage array
+ *
+ * @since 1.9
+ *
+ * @return array
+ */
+ public function toArray() {
+ return $this->storage;
+ }
+
+ /**
+ * Merges elements of one or more arrays together
+ *
+ * @since 1.9
+ *
+ * @param array $mergeable
+ */
+ public function merge( array $mergeable ) {
+ $this->storage = array_merge( $this->storage, $mergeable );
+ }
+
+ /**
+ * Register an object via magic method __set
+ *
+ * @par Example:
+ * @code
+ * $container = new EmptyDependencyContainer()
+ *
+ * // Eager loading (do everything when asked)
+ * $container->title = new Title() or
+ *
+ * // Lazy loading (only do an instanitation when required)
+ * $container->diWikiPage = function ( DependencyBuilder $builder ) {
+ * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' )
);
+ * } );
+ * @endcode
+ *
+ * @since 1.9
+ *
+ * @param string $key
+ * @param mixed $value
+ */
+ public function __set( $objectName, $objectSignature ) {
+ $this->set( $objectName, $objectSignature );
+ }
+
+ /**
+ * Register an object
+ *
+ * @par Example:
+ * @code
+ * $container = new EmptyDependencyContainer()
+ *
+ * // Eager loading (do everything when asked)
+ * $container->registerObject( 'Title', new Title() ) or
+ *
+ * // Lazy loading (only do an instanitation when required)
+ * $container->registerObject( 'DIWikiPage', function (
DependencyBuilder $builder ) {
+ * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' )
);
+ * } );
+ * @endcode
+ *
+ * @since 1.9
+ *
+ * @param string $objectName
+ * @param mixed $signature
+ */
+ public function registerObject( $objectName, $objectSignature ) {
+ $this->set( $objectName, $objectSignature );
+ }
+
+}
diff --git a/includes/dic/DependencyBuilder.php
b/includes/dic/DependencyBuilder.php
new file mode 100644
index 0000000..dfe61c3
--- /dev/null
+++ b/includes/dic/DependencyBuilder.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Interfaces specifying a DependencyBuilder
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Interface that specifies a method to create a new object
+ *
+ * @ingroup DependencyBuilder
+ */
+interface DependencyFactory {
+
+ /**
+ * Returns a dependency object
+ *
+ * @since 1.9
+ */
+ public function newObject( $objectName );
+
+}
+
+/**
+ * Interface that specifies methods to handle injection container and objects
+ *
+ * @ingroup DependencyBuilder
+ */
+interface DependencyBuilder extends DependencyFactory {
+
+ /**
+ * Returns invoked dependency container object
+ *
+ * @since 1.9
+ *
+ * @return DependencyContainer
+ */
+ public function getContainer();
+
+ /**
+ * Returns an invoked constructor argument
+ *
+ * @since 1.9
+ *
+ * @param string $key
+ */
+ public function getArgument( $key );
+
+ /**
+ * Adds an argument that can be used during object creation
+ *
+ * @since 1.9
+ *
+ * @param string $key
+ * @param mixed $value
+ */
+ public function addArgument( $key, $value );
+
+}
diff --git a/includes/dic/DependencyContainer.php
b/includes/dic/DependencyContainer.php
new file mode 100644
index 0000000..72b8ff6
--- /dev/null
+++ b/includes/dic/DependencyContainer.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Provides interfaces for dependency injection
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Interface specifying a dependency object
+ *
+ * @ingroup DependencyContainer
+ */
+interface DependencyObject {
+
+ /**
+ * Register a dependency object
+ *
+ * @since 1.9
+ */
+ public function registerObject( $objectName, $objectSignature );
+
+}
+
+/**
+ * Interface specifying a dependency container
+ *
+ * @ingroup DependencyContainer
+ */
+interface DependencyContainer extends DependencyObject, Accessible,
Changeable, Combinable {}
diff --git a/includes/dic/DependencyInjector.php
b/includes/dic/DependencyInjector.php
new file mode 100644
index 0000000..a1479b5
--- /dev/null
+++ b/includes/dic/DependencyInjector.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Abstract class that implements the DependencyRequestor
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Abstract class that implements the DependencyRequestor to enable convenience
+ * access to an injected DependencyBuilder
+ *
+ * @par Example:
+ * @code
+ * class FooClass extends DependencyInjector { ... }
+ *
+ * $fooClass = new FooClass( ... )
+ * $fooClass->setDependencyBuilder( new SimpleDependencyBuilder(
+ * new GenericDependencyContainer()
+ * ) );
+ *
+ * $fooClass->getDependencyBuilder()->newObject( 'Bar' );
+ * @endcode
+ *
+ * @since 1.9
+ *
+ * @ingroup DependencyRequestor
+ */
+abstract class DependencyInjector implements DependencyRequestor {
+
+ /** @var DependencyBuilder */
+ protected $dependencyBuilder;
+
+ /**
+ * @see DependencyRequestor::setDependencyBuilder
+ *
+ * @since 1.9
+ *
+ * @param DependencyBuilder $builder
+ */
+ public function setDependencyBuilder( DependencyBuilder $builder ) {
+ $this->dependencyBuilder = $builder;
+ }
+
+ /**
+ * @see DependencyRequestor::getDependencyBuilder
+ *
+ * @since 1.9
+ *
+ * @return DependencyBuilder
+ */
+ public function getDependencyBuilder() {
+ return $this->dependencyBuilder;
+ }
+}
diff --git a/includes/dic/DependencyRequestor.php
b/includes/dic/DependencyRequestor.php
new file mode 100644
index 0000000..21c970f
--- /dev/null
+++ b/includes/dic/DependencyRequestor.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace SMW;
+
+use InvalidArgumentException;
+use OutOfBoundsException;
+
+/**
+ * Interface specifying access to a DependencyBuilder
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Interface specifying access to a DependencyBuilder within a client that
+ * requests dependency injection
+ *
+ * @ingroup DependencyRequestor
+ */
+interface DependencyRequestor {
+
+ /**
+ * Sets DependencyBuilder
+ *
+ * @since 1.9
+ *
+ * @param DependencyBuilder $builder
+ */
+ public function setDependencyBuilder( DependencyBuilder $builder );
+
+ /**
+ * Returns invoked DependencyBuilder
+ *
+ * @since 1.9
+ *
+ * @return DependencyBuilder
+ */
+ public function getDependencyBuilder();
+
+}
diff --git a/includes/dic/EmptyDependencyContainer.php
b/includes/dic/EmptyDependencyContainer.php
new file mode 100644
index 0000000..8f1ad5d
--- /dev/null
+++ b/includes/dic/EmptyDependencyContainer.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Provides an empty DependencyContainer entity
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Provides an empty DependencyContainer entity
+ *
+ * @ingroup DependencyContainer
+ */
+class EmptyDependencyContainer extends BaseDependencyContainer {}
diff --git a/includes/dic/README.mediawiki b/includes/dic/README.mediawiki
new file mode 100644
index 0000000..a737b44
--- /dev/null
+++ b/includes/dic/README.mediawiki
@@ -0,0 +1,97 @@
+A basic dependency injection framework to enable object injection for
immutable or service objects in Semantic MediaWiki.
+
+== Overview ==
+* Support of predefined object definitions residing in a DependencyContainer
object
+* Support to register of multiple container
+* Support for eager or lazy loading of objects
+* Support for "named" constructor arguments
+
+=== Objects ===
+<pre>
+// Injector
+DependencyRequestor
+ -> DependencyInjector
+
+// Builder
+DependencyFactory
+ -> DependencyBuilder
+ -> SimpleDependencyBuilder
+
+// Definitions
+DependencyObject
+ -> DependencyContainer
+ -> BaseDependencyContainer
+ -> EmptyDependencyContainer
+ -> SharedDependencyContainer
+</pre>
+
+=== Scope ===
+{|
+| Scope
+| Description
+|-
+| prototype (default)
+| Each injection or call of the newObject() method returns a new instance
+|}
+
+== DependencyContainer ==
+* DependencyObject an interface that specifies a method to register a
dependency object
+* DependencyContainer an interface that specifies methods to retrieve and
store object definitions
+* BaseDependencyContainer implements the DependencyContainer
+* EmptyDependencyContainer an empty container that extends
BaseDependencyContainer.
+* SharedDependencyContainer implements common object definitions used during
Semantic MediaWiki's life cycle.
+
+== DependencyBuilder ==
+* DependencyFactory an interface that specifies a method to create a new object
+* DependencyBuilder an interface specifies methods to handle injection
container and objects
+* SimpleDependencyBuilder implementing the DependencyBuilder to enable access
to DependencyContainer objects and other invoked arguments
+
+== DependencyInjector ==
+* DependencyRequestor an interface specifying access to a DependencyBuilder
within a client that requests dependency injection
+* DependencyInjector an abstract class that implements the DependencyRequestor
to enable convenience access to an injected DependencyBuilder
+
+== Example ==
+=== SimpleDependencyBuilder ===
+<pre>
+$container = new EmptyDependencyContainer();
+
+// Register object (eager loading)
+$container->title = new Title();
+$container->registerObject( 'Foo', new \stdClass );
+
+// Register object (lazy loading)
+$container->property = function ( DependencyBuilder $builder ) {
+ return new DIProperty( ... );
+} );
+
+$container->registerObject( 'DIWikiPage', function ( DependencyBuilder
$builder ) {
+ return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' ) );
+} );
+
+// Access objects through a builder
+$builder = new SimpleDependencyBuilder( $container );
+
+$builder->newObject( 'Foo' );
+$builder->newObject( 'title' );
+$builder->property;
+
+// Invoke necessary arguments
+$builder->addArgument( 'Title', $builder->newObject( 'title' ) );
+$builder->newObject( 'DIWikiPage' );
+
+// Deferred object registration using the builder
+$builder->getContainer()->registerObject( 'Bar', new Fruits() );
+
+$builder->newObject( 'Bar' );
+</pre>
+=== DependencyInjector ===
+<pre>
+class FooClass extends DependencyInjector { ... }
+
+$fooClass = new FooClass( ... )
+$fooClass->setDependencyBuilder( new SimpleDependencyBuilder() );
+
+$fooClass->getDependencyBuilder()->newObject( 'Bar' );
+</pre>
+
+__NOTOC__
\ No newline at end of file
diff --git a/includes/dic/SharedDependencyContainer.php
b/includes/dic/SharedDependencyContainer.php
new file mode 100644
index 0000000..2bf6798
--- /dev/null
+++ b/includes/dic/SharedDependencyContainer.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Extends the BaseDependencyContainer
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Extends the BaseDependencyContainer to provide general purpose dependecy
+ * object definitions
+ *
+ * @ingroup DependencyContainer
+ */
+class SharedDependencyContainer extends BaseDependencyContainer {
+
+ /**
+ * @since 1.9
+ */
+ public function __construct() {
+ $this->load();
+ }
+
+ /**
+ * Load pre-existing object definitions
+ *
+ * @since 1.9
+ */
+ public function load() {
+
+ $this->registerObject( 'Settings', function () {
+ return Settings::newFromGlobals();
+ } );
+
+ $this->registerObject( 'Store', function ( DependencyBuilder
$builder ) {
+ return StoreFactory::getStore( $builder->newObject(
'Settings' )->get( 'smwgDefaultStore' ) );
+ } );
+
+ $this->registerObject( 'CacheHandler', function (
DependencyBuilder $builder ) {
+ return CacheHandler::newFromId( $builder->newObject(
'Settings' )->get( 'smwgCacheType' ) );
+ } );
+
+ $this->registerObject( 'ParserData', function (
DependencyBuilder $builder ) {
+ return new ParserData(
+ $builder->getArgument( 'Title' ),
+ $builder->getArgument( 'ParserOutput' )
+ );
+ } );
+
+ // $this->set( 'FactboxPresenter', function ( DependencyBuilder
$builder ) {
+ // $outputPage = $builder->getArgument( 'OutputPage' );
+ // return new FactboxPresenter( $outputPage,
$builder->newObject( 'Settings' ) );
+ // } );
+
+ // $this->set( 'Factbox', function ( DependencyBuilder $builder
) {
+ // return new Factbox(
+ // $builder->newObject( 'Store' ),
+ // $builder->getArgument( 'SMW\ParserData' ),
+ // $builder->getArgument( 'SMW\Settings' ),
+ // $builder->getArgument( 'RequestContext' )
+ // );
+ // } );
+
+ }
+
+}
diff --git a/includes/DependencyBuilder.php
b/includes/dic/SimpleDependencyBuilder.php
similarity index 76%
rename from includes/DependencyBuilder.php
rename to includes/dic/SimpleDependencyBuilder.php
index c2ee5a5..6e38729 100644
--- a/includes/DependencyBuilder.php
+++ b/includes/dic/SimpleDependencyBuilder.php
@@ -6,7 +6,7 @@
use OutOfBoundsException;
/**
- * DependencyBuilder base class
+ * Implements the DependencyBuilder
*
* @file
*
@@ -17,57 +17,8 @@
*/
/**
- * Specifies a method to create a new object
- *
- * @ingroup DependencyBuilder
- */
-interface DependencyFactory {
-
- /**
- * Returns a dependency object
- *
- * @since 1.9
- */
- public function newObject( $objectName );
-
-}
-
-/**
- * Extends the DependencyFactory interface, and specifies all methods required
- * to create an injection object
- *
- * @ingroup DependencyBuilder
- */
-interface DependencyBuilder extends DependencyFactory {
-
- /**
- * Returns dependency container object
- *
- * @since 1.9
- *
- * @return DependencyContainer
- */
- public function getContainer();
-
- /**
- * Returns an invoked constructor arguments
- *
- * @since 1.9
- */
- public function getArgument( $key );
-
- /**
- * Adds an arguments that can be used during object creation
- *
- * @since 1.9
- */
- public function addArgument( $key, $value );
-
-}
-
-/**
- * Basic DependencyBuilder implementation to access DependencyContainer objects
- * and invoked arguments
+ * Basic implementation of the DependencyBuilder interface to enable access to
+ * DependencyContainer objects and other invoked arguments
*
* @ingroup DependencyBuilder
*/
@@ -84,7 +35,6 @@
* @par Example:
* @code
* $builder = new SimpleDependencyBuilder() or
- * $builder = new SimpleDependencyBuilder( new
CommonDependencyContainer() ) or
* $builder = new SimpleDependencyBuilder( new
EmptyDependencyContainer() )
* @endcode
*
@@ -127,18 +77,17 @@
}
/**
- * Returns the dependency container
+ * @see DependencyBuilder::getArgument
*
* @par Example:
* @code
- * $builder = new SimpleDependencyBuilder()
+ * $builder = new SimpleDependencyBuilder( new
EmptyDependencyContainer() );
+ * $builder->getContainer() returns EmptyDependencyContainer
*
- * // Eager loading (do everything when asked for)
+ * // Register additional objects during runtime
* $builder->getContainer()->registerObject( 'Title', new Title() ) or
- *
- * // Lazy loading (only do an instanitation when required)
* $builder->getContainer()->registerObject( 'DIWikiPage', function (
DependencyBuilder $builder ) {
- * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title' )
);
+ * return DIWikiPage::newFromTitle( $builder->getArgument( 'Title'
) );
* } );
* @endcode
*
@@ -174,6 +123,17 @@
/**
* Build dynamic entities via magic method __get
*
+ * @par Example:
+ * @code
+ * $builder = new SimpleDependencyBuilder( ... )
+ *
+ * // Register object using __Set
+ * $builder->getContainer()->title = new Title()
+ *
+ * // Retrieve object using __get
+ * $builder->title returns Title object
+ * @endcode
+ *
* @param string $objectName
*/
public function __get( $objectName ) {
@@ -181,7 +141,7 @@
}
/**
- * Returns an invoked argument
+ * @see DependencyBuilder::getArgument
*
* @note Arguments are being preceded by a "arg_" to distingiush those
* objects internally from regisered DI objects. The handling is only
@@ -204,7 +164,7 @@
}
/**
- * Adds an argument (normally used during object creation)
+ * @see DependencyBuilder::addArgument
*
* @since 1.9
*
@@ -226,7 +186,7 @@
}
/**
- * Register arguments that were used during object invocation
+ * Auto registeration for arguments that were used during object
invocation
*
* @note Only the first array contains arguments relevant to the object
* creation
diff --git a/includes/hooks/ArticlePurge.php b/includes/hooks/ArticlePurge.php
index 38fe57d..0d79165 100644
--- a/includes/hooks/ArticlePurge.php
+++ b/includes/hooks/ArticlePurge.php
@@ -25,7 +25,7 @@
*
* @ingroup Hook
*/
-class ArticlePurge extends DependencyInjector {
+class ArticlePurge extends InjectableHook {
/** @var OutputPage */
protected $wikiPage = null;
diff --git a/includes/hooks/FunctionHookRegistry.php
b/includes/hooks/FunctionHookRegistry.php
new file mode 100644
index 0000000..d5719dc
--- /dev/null
+++ b/includes/hooks/FunctionHookRegistry.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Register a function hook
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Register a function hook
+ *
+ * @ingroup Hook
+ */
+class FunctionHookRegistry {
+
+ /**
+ * Method to register a hook and its DependencyBuilder
+ *
+ * @since 1.9
+ *
+ * @param InjectableHook $hook
+ *
+ * @return InjectableHook
+ */
+ public static function register( InjectableHook $hook ) {
+ $hook->setDependencyBuilder( new SimpleDependencyBuilder( new
SharedDependencyContainer() ) );
+ return $hook;
+ }
+
+}
diff --git a/includes/hooks/HooksLoader.php b/includes/hooks/HooksLoader.php
index 35a21b2..799c099 100644
--- a/includes/hooks/HooksLoader.php
+++ b/includes/hooks/HooksLoader.php
@@ -33,14 +33,4 @@
return $hook;
}
- /**
- * This being temporary to demonstrate the injection of the
DependencyBuilder
- *
- * @since 1.9
- */
- public static function prepare( $hook ) {
- $hook->setDependencyBuilder( new SimpleDependencyBuilder( new
CommonDependencyContainer() ) );
- return $hook;
- }
-
}
diff --git a/includes/hooks/InjectableHook.php
b/includes/hooks/InjectableHook.php
new file mode 100644
index 0000000..1118e14
--- /dev/null
+++ b/includes/hooks/InjectableHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Specifies an injectable hook class
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Specifies an injectable hook class
+ *
+ * @ingroup Hook
+ */
+abstract class InjectableHook extends DependencyInjector {
+
+ /**
+ * Main method that initiates the processing of the registered
+ * hook class
+ *
+ * @since 1.9
+ *
+ * @return true
+ */
+ public abstract function process();
+
+}
diff --git a/tests/phpunit/includes/DependencyInjectorTest.php
b/tests/phpunit/includes/dic/DependencyInjectorTest.php
similarity index 100%
rename from tests/phpunit/includes/DependencyInjectorTest.php
rename to tests/phpunit/includes/dic/DependencyInjectorTest.php
diff --git a/tests/phpunit/includes/CommonDependencyContainerTest.php
b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php
similarity index 80%
rename from tests/phpunit/includes/CommonDependencyContainerTest.php
rename to tests/phpunit/includes/dic/SharedDependencyContainerTest.php
index d142894..eda817d 100644
--- a/tests/phpunit/includes/CommonDependencyContainerTest.php
+++ b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php
@@ -2,14 +2,14 @@
namespace SMW\Test;
-use SMW\CommonDependencyContainer;
+use SMW\SharedDependencyContainer;
use SMW\SimpleDependencyBuilder;
use SMW\DependencyBuilder;
use SMW\DependencyContainer;
/**
- * Tests for the CommonDependencyContainer
+ * Tests for the SharedDependencyContainer
*
* @file
*
@@ -20,16 +20,16 @@
*/
/**
- * @covers \SMW\CommonDependencyContainer
+ * @covers \SMW\SharedDependencyContainer
* @covers \SMW\SimpleDependencyBuilder
- * @covers \SMW\DependencyContainerBase
+ * @covers \SMW\BaseDependencyContainer
*
* @ingroup Test
*
* @group SMW
* @group SMWExtension
*/
-class CommonDependencyContainerTest extends SemanticMediaWikiTestCase {
+class SharedDependencyContainerTest extends SemanticMediaWikiTestCase {
/**
* Returns the name of the class to be tested
@@ -60,9 +60,9 @@
*
* @since 1.9
*/
- public function testCommonDependencyContainer() {
+ public function testSharedDependencyContainer() {
- $instance = $this->getInstance( new CommonDependencyContainer()
);
+ $instance = $this->getInstance( new SharedDependencyContainer()
);
$this->assertInstanceOf( '\SMW\Settings', $instance->newObject(
'Settings' ) );
$this->assertInstanceOf( '\SMW\Store', $instance->newObject(
'Store' ) );
diff --git a/tests/phpunit/includes/SimpleDependencyBuilderTest.php
b/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
similarity index 79%
rename from tests/phpunit/includes/SimpleDependencyBuilderTest.php
rename to tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
index 60bf94a..e384ff0 100644
--- a/tests/phpunit/includes/SimpleDependencyBuilderTest.php
+++ b/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php
@@ -72,7 +72,7 @@
*
* @return SimpleDependencyBuilder
*/
- private function getInstance( $dependencyContainer = null ) {
+ private function newInstance( $dependencyContainer = null ) {
return new SimpleDependencyBuilder( $dependencyContainer );
}
@@ -82,18 +82,18 @@
* @since 1.9
*/
public function testConstructor() {
- $this->assertInstanceOf( $this->getClass(),
$this->getInstance() );
+ $this->assertInstanceOf( $this->getClass(),
$this->newInstance() );
}
/**
- * @test SimpleDependencyBuilder::registerObject
+ * @test SimpleDependencyBuilder::registerContainer
* @test SimpleDependencyBuilder::newObject
*
* @since 1.9
*/
public function testRegisterContainer() {
- $instance = $this->getInstance();
+ $instance = $this->newInstance();
// Register container
$container = $this->newDependencyContainer( array( 'Test' =>
'123' ) );
@@ -105,8 +105,31 @@
$container = $this->newDependencyContainer( array( 'Test2' =>
9001 ) );
$instance->registerContainer( $container );
+ // Verifies that both objects are avilable
$this->assertEquals( '123', $instance->newObject( 'Test' ) );
$this->assertEquals( 9001, $instance->newObject( 'Test2' ) );
+
+ // Register another container containing the same identifier but
+ // with a different definition
+ $container = $this->newDependencyContainer( array( 'Test2' =>
1009 ) );
+ $instance->registerContainer( $container );
+ $this->assertEquals( 1009, $instance->newObject( 'Test2' ) );
+
+ }
+
+ /**
+ * @test SimpleDependencyBuilder::getContainer
+ * @test SimpleDependencyBuilder::registerObject
+ * @test SimpleDependencyBuilder::newObject
+ *
+ * @since 1.9
+ */
+ public function testRegisterObject() {
+
+ $instance = $this->newInstance();
+ $instance->getContainer()->registerObject( 'Test', new
\stdClass );
+
+ $this->assertInstanceOf( '\stdClass', $instance->newObject(
'Test' ) );
}
@@ -116,9 +139,9 @@
*
* @since 1.9
*/
- public function testRegisterObjectMagicMethod() {
+ public function testRegisterObjectUsingMagicMethod() {
- $instance = $this->getInstance();
+ $instance = $this->newInstance();
// Register objects
$container = new EmptyDependencyContainer();
@@ -137,35 +160,25 @@
// Adds necessary argument object needed for the DIWikiPage
build process
$instance->addArgument( 'Title', $instance->someFunnyTitle );
+
$this->assertInstanceOf( '\SMW\DIWikiPage',
$instance->diwikipage );
$this->assertInstanceOf( '\SMW\DIWikiPage',
$instance->newObject( 'diwikipage' ) );
-
$this->assertTrue( $instance->diwikipage !==
$instance->newObject( 'diwikipage' ) );
- $instance->registerContainer( new EmptyDependencyContainer() );
+ // Clear registered container
+ $instance->registerContainer( new EmptyDependencyContainer() );
$instance->getContainer()->thisTitleIsEven = $this->newTitle();
+ // Object is using argument that where invoked using the __set
method
+ // and is evenly accessible during the build process using
newObject()
+ // method
$instance->getContainer()->tanomoshi = function (
DependencyBuilder $builder ) {
return DIWikiPage::newFromTitle( $builder->newObject(
'thisTitleIsEven' ) );
};
$this->assertInstanceOf( 'Title', $instance->newObject(
'thisTitleIsEven' ) );
$this->assertInstanceOf( '\SMW\DIWikiPage',
$instance->newObject( 'tanomoshi' ) );
-
- }
-
- /**
- * @test SimpleDependencyBuilder::getContainer
- * @test SimpleDependencyBuilder::newObject
- *
- * @since 1.9
- */
- public function testRegisterObject() {
-
- $instance = $this->getInstance();
- $instance->getContainer()->registerObject( 'Test', new
\stdClass );
-
- $this->assertInstanceOf( '\stdClass', $instance->newObject(
'Test' ) );
+ $this->assertInstanceOf( '\SMW\DIWikiPage',
$instance->tanomoshi );
}
@@ -178,11 +191,11 @@
*/
public function testAddGetArguments() {
- // Add argument using a setter
- $instance = $this->getInstance();
- $title = $this->newMockObject()->getMockTitle();
+ // Add argument using a setter (mockTitle)
+ $instance = $this->newInstance();
+ $mockTitle = $this->newMockObject()->getMockTitle();
- $instance->addArgument( 'Title', $title );
+ $instance->addArgument( 'Title', $mockTitle );
$instance->getContainer()->registerObject( 'Test', function (
DependencyBuilder $builder ) {
return DIWikiPage::newFromTitle( $builder->getArgument(
'Title' ) );
} );
@@ -190,8 +203,8 @@
$this->assertInstanceOf( '\SMW\DIWikiPage',
$instance->newObject( 'Test' ) );
$this->assertInstanceOf( 'Title', $instance->newObject( 'Test'
)->getTitle() );
- // Compare added argument and the object provieded by the DI
object
- $instance = $this->getInstance();
+ // Add argument using a setter ("real" object)
+ $instance = $this->newInstance();
$title = $this->newTitle( NS_MAIN, 'Lala' );
$instance->addArgument( 'Title', $title );
@@ -201,7 +214,8 @@
$this->assertEquals( $title, $instance->newObject( 'Test2'
)->getTitle() );
- $instance = $this->getInstance();
+ // Argument auto registration
+ $instance = $this->newInstance();
$title = $this->newTitle( NS_MAIN, 'Lila' );
$instance->getContainer()->registerObject( 'Test3', function (
DependencyBuilder $builder ) {
@@ -220,7 +234,7 @@
public function testGetArgumentOutOfBoundsException() {
$this->setExpectedException( 'OutOfBoundsException' );
- $this->getInstance()->getArgument( 'Title' );
+ $this->newInstance()->getArgument( 'Title' );
}
@@ -232,7 +246,7 @@
public function testAddArgumentInvalidArgument() {
$this->setExpectedException( 'InvalidArgumentException' );
- $this->getInstance()->addArgument( $this->newTitle(), 'Title' );
+ $this->newInstance()->addArgument( $this->newTitle(), 'Title' );
}
@@ -244,7 +258,7 @@
public function testNewObjectInvalidArgument() {
$this->setExpectedException( 'InvalidArgumentException' );
- $this->getInstance()->newObject( new \stdclass );
+ $this->newInstance()->newObject( new \stdclass );
}
@@ -256,7 +270,7 @@
public function testUnknownObject() {
$this->setExpectedException( 'OutOfBoundsException' );
- $this->getInstance()->newObject( 'Foo' );
+ $this->newInstance()->newObject( 'Foo' );
}
diff --git a/tests/phpunit/includes/hooks/FunctionHookRegistryTest.php
b/tests/phpunit/includes/hooks/FunctionHookRegistryTest.php
new file mode 100644
index 0000000..31b2627
--- /dev/null
+++ b/tests/phpunit/includes/hooks/FunctionHookRegistryTest.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\FunctionHookRegistry;
+
+/**
+ * Tests for the FunctionHookRegistry class
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\FunctionHookRegistry
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class FunctionHookRegistryTest extends SemanticMediaWikiTestCase {
+
+ /**
+ * Returns the name of the class to be tested
+ *
+ * @return string|false
+ */
+ public function getClass() {
+ return '\SMW\FunctionHookRegistry';
+ }
+
+ /**
+ * Helper method that returns a InjectableHook object
+ *
+ * @since 1.9
+ *
+ * @return InjectableHook
+ */
+ private function newHook() {
+ return $this->getMockForAbstractClass( '\SMW\InjectableHook' );
+ }
+
+ /**
+ * Helper method that returns a FunctionHookRegistry object
+ *
+ * @since 1.9
+ *
+ * @return FunctionHookRegistry
+ */
+ private function newInstance() {
+ return new FunctionHookRegistry();
+ }
+
+ /**
+ * @test FunctionHookRegistry::__construct
+ *
+ * @since 1.9
+ */
+ public function testConstructor() {
+ $this->assertInstanceOf(
+ '\SMW\InjectableHook',
+ FunctionHookRegistry::register( $this->newHook() ),
+ 'Failed asserting InjectableHook instance'
+ );
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/80070
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1cd202b322acd66562f640ef91932df7a272e63b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticMediaWiki
Gerrit-Branch: master
Gerrit-Owner: Mwjames <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits