first commit
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\Registry;
|
||||
|
||||
/**
|
||||
* An abstract class for dependency types.
|
||||
*
|
||||
* Dependency types are instances of a dependency used by the
|
||||
* Dependency Injection Container for storing dependencies to invoke as they
|
||||
* are needed.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
abstract class AbstractDependencyType {
|
||||
|
||||
/**
|
||||
* Holds a callable or value provided for this type.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $callable_or_value;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param mixed $callable_or_value A callable or value for the dependency
|
||||
* type instance.
|
||||
*/
|
||||
public function __construct( $callable_or_value ) {
|
||||
$this->callable_or_value = $callable_or_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolver for the internal dependency value.
|
||||
*
|
||||
* @param Container $container The Dependency Injection Container.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolve_value( Container $container ) {
|
||||
$callback = $this->callable_or_value;
|
||||
return \is_callable( $callback )
|
||||
? $callback( $container )
|
||||
: $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value stored internally for this DependencyType
|
||||
*
|
||||
* @param Container $container The Dependency Injection Container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function get( Container $container );
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\Registry;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* A simple Dependency Injection Container
|
||||
*
|
||||
* This is used to manage dependencies used throughout the plugin.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class Container {
|
||||
|
||||
/**
|
||||
* A map of Dependency Type objects used to resolve dependencies.
|
||||
*
|
||||
* @var AbstractDependencyType[]
|
||||
*/
|
||||
private $registry = [];
|
||||
|
||||
/**
|
||||
* Public api for adding a factory to the container.
|
||||
*
|
||||
* Factory dependencies will have the instantiation callback invoked
|
||||
* every time the dependency is requested.
|
||||
*
|
||||
* Typical Usage:
|
||||
*
|
||||
* ```
|
||||
* $container->register( MyClass::class, $container->factory( $mycallback ) );
|
||||
* ```
|
||||
*
|
||||
* @param Closure $instantiation_callback This will be invoked when the
|
||||
* dependency is required. It will
|
||||
* receive an instance of this
|
||||
* container so the callback can
|
||||
* retrieve dependencies from the
|
||||
* container.
|
||||
*
|
||||
* @return FactoryType An instance of the FactoryType dependency.
|
||||
*/
|
||||
public function factory( Closure $instantiation_callback ) {
|
||||
return new FactoryType( $instantiation_callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for registering a new dependency with the container.
|
||||
*
|
||||
* By default, the $value will be added as a shared dependency. This means
|
||||
* that it will be a single instance shared among any other classes having
|
||||
* that dependency.
|
||||
*
|
||||
* If you want a new instance every time it's required, then wrap the value
|
||||
* in a call to the factory method (@see Container::factory for example)
|
||||
*
|
||||
* Note: Currently if the provided id already is registered in the container,
|
||||
* the provided value is ignored.
|
||||
*
|
||||
* @param string $id A unique string identifier for the provided value.
|
||||
* Typically it's the fully qualified name for the
|
||||
* dependency.
|
||||
* @param mixed $value The value for the dependency. Typically, this is a
|
||||
* closure that will create the class instance needed.
|
||||
*/
|
||||
public function register( $id, $value ) {
|
||||
if ( empty( $this->registry[ $id ] ) ) {
|
||||
if ( ! $value instanceof FactoryType ) {
|
||||
$value = new SharedType( $value );
|
||||
}
|
||||
$this->registry[ $id ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for retrieving the dependency stored in the container for the
|
||||
* given identifier.
|
||||
*
|
||||
* @param string $id The identifier for the dependency being retrieved.
|
||||
* @throws Exception If there is no dependency for the given identifier in
|
||||
* the container.
|
||||
*
|
||||
* @return mixed Typically a class instance.
|
||||
*/
|
||||
public function get( $id ) {
|
||||
if ( ! isset( $this->registry[ $id ] ) ) {
|
||||
// this is a developer facing exception, hence it is not localized.
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Cannot construct an instance of %s because it has not been registered.',
|
||||
$id
|
||||
)
|
||||
);
|
||||
}
|
||||
return $this->registry[ $id ]->get( $this );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\Registry;
|
||||
|
||||
/**
|
||||
* Definition for the FactoryType dependency type.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class FactoryType extends AbstractDependencyType {
|
||||
/**
|
||||
* Invokes and returns the value from the stored internal callback.
|
||||
*
|
||||
* @param Container $container An instance of the dependency injection
|
||||
* container.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get( Container $container ) {
|
||||
return $this->resolve_value( $container );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\Registry;
|
||||
|
||||
/**
|
||||
* A definition for the SharedType dependency type.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class SharedType extends AbstractDependencyType {
|
||||
|
||||
/**
|
||||
* Holds a cached instance of the value stored (or returned) internally.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $shared_instance;
|
||||
|
||||
/**
|
||||
* Returns the internal stored and shared value after initial generation.
|
||||
*
|
||||
* @param Container $container An instance of the dependency injection
|
||||
* container.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get( Container $container ) {
|
||||
if ( empty( $this->shared_instance ) ) {
|
||||
$this->shared_instance = $this->resolve_value( $container );
|
||||
}
|
||||
return $this->shared_instance;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user