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

Reply via email to