Merged Linject into the core IoC container.
This commit is contained in:
parent
30c87b9245
commit
348ff778ed
|
@ -71,6 +71,7 @@ ## Laravel 3.2
|
||||||
- Added Response::json method for creating JSON responses.
|
- Added Response::json method for creating JSON responses.
|
||||||
- Added Response::eloquent method for creating Eloquent responses.
|
- Added Response::eloquent method for creating Eloquent responses.
|
||||||
- Fixed bug when using many-to-many relationships on non-default database connection.
|
- Fixed bug when using many-to-many relationships on non-default database connection.
|
||||||
|
- Added true reflection based IoC to container.
|
||||||
|
|
||||||
<a name="upgrade-3.2"></a>
|
<a name="upgrade-3.2"></a>
|
||||||
## Upgrading From 3.1
|
## Upgrading From 3.1
|
||||||
|
|
144
laravel/ioc.php
144
laravel/ioc.php
|
@ -20,11 +20,11 @@ class IoC {
|
||||||
* Register an object and its resolver.
|
* Register an object and its resolver.
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param Closure $resolver
|
* @param mixed $resolver
|
||||||
* @param bool $singleton
|
* @param bool $singleton
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function register($name, Closure $resolver, $singleton = false)
|
public static function register($name, $resolver, $singleton = false)
|
||||||
{
|
{
|
||||||
static::$registry[$name] = compact('resolver', 'singleton');
|
static::$registry[$name] = compact('resolver', 'singleton');
|
||||||
}
|
}
|
||||||
|
@ -72,39 +72,7 @@ public static function instance($name, $instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a controller with the IoC container.
|
* Resolve a given type to an instance.
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param Closure $resolver
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function controller($name, $resolver)
|
|
||||||
{
|
|
||||||
static::register("controller: {$name}", $resolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve a core Laravel class from the container.
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* // Resolve the "laravel.router" class from the container
|
|
||||||
* $input = IoC::core('router');
|
|
||||||
*
|
|
||||||
* // Equivalent resolution of the router using the "resolve" method
|
|
||||||
* $input = IoC::resolve('laravel.router');
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param array $parameters
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function core($name, $parameters = array())
|
|
||||||
{
|
|
||||||
return static::resolve("laravel.{$name}", $parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve an object instance from the container.
|
|
||||||
*
|
*
|
||||||
* <code>
|
* <code>
|
||||||
* // Get an instance of the "mailer" object registered in the container
|
* // Get an instance of the "mailer" object registered in the container
|
||||||
|
@ -114,28 +82,112 @@ public static function core($name, $parameters = array())
|
||||||
* $mailer = IoC::resolve('mailer', array('test'));
|
* $mailer = IoC::resolve('mailer', array('test'));
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $type
|
||||||
* @param array $parameters
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function resolve($name, $parameters = array())
|
public static function resolve($type, $parameters = array())
|
||||||
{
|
{
|
||||||
if (array_key_exists($name, static::$singletons))
|
// If an instance of the type is currently being managed as a singleton, we will
|
||||||
|
// just return the existing instance instead of instantiating a fresh instance
|
||||||
|
// so the developer can keep re-using the exact same object instance from us.
|
||||||
|
if (isset(static::$singletons[$type]))
|
||||||
{
|
{
|
||||||
return static::$singletons[$name];
|
return static::$singletons[$type];
|
||||||
}
|
}
|
||||||
|
|
||||||
$object = call_user_func_array(static::$registry[$name]['resolver'], $parameters);
|
$concrete = array_get(static::$registry, "{$type}.resolver", $type);
|
||||||
|
|
||||||
// If the resolver is registering as a singleton resolver, we will cache
|
// We're ready to instantiate an instance of the concrete type registered for
|
||||||
// the instance of the object in the container so we can resolve it next
|
// the binding. This will instantiate the type, as well as resolve any of
|
||||||
// time without having to instantiate a brand new instance.
|
// its nested dependencies recursively until they are each resolved.
|
||||||
if (static::$registry[$name]['singleton'])
|
if ($concrete == $type or $concrete instanceof Closure)
|
||||||
{
|
{
|
||||||
return static::$singletons[$name] = $object;
|
$object = static::build($concrete);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$object = static::resolve($concrete);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the requested type is registered as a singleton, we want to cache off
|
||||||
|
// the instance in memory so we can return it later without creating an
|
||||||
|
// entirely new instances of the object on each subsequent request.
|
||||||
|
if (isset(static::$registry[$type]['singleton']))
|
||||||
|
{
|
||||||
|
static::$singletons[$type] = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate an instance of the given type.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param array $parameters
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected static function build($type, $parameters = array())
|
||||||
|
{
|
||||||
|
// If the concrete type is actually a Closure, we will just execute it and
|
||||||
|
// hand back the results of the function, which allows functions to be
|
||||||
|
// used as resolvers for more fine-tuned resolution of the objects.
|
||||||
|
if ($type instanceof Closure)
|
||||||
|
{
|
||||||
|
return call_user_func_array($type, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflector = new \ReflectionClass($type);
|
||||||
|
|
||||||
|
// If the type is not instantiable, the developer is attempting to resolve
|
||||||
|
// an abstract type such as an Interface of Abstract Class and there is
|
||||||
|
// no binding registered for the abstraction so we need to bail out.
|
||||||
|
if ( ! $reflector->isInstantiable())
|
||||||
|
{
|
||||||
|
throw new Exception("Resolution target [$type] is not instantiable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$constructor = $reflector->getConstructor();
|
||||||
|
|
||||||
|
// If there is no constructor, that means there are no dependencies and
|
||||||
|
// we can just resolve an instance of the object right away without
|
||||||
|
// resolving any other types or dependencies from the container.
|
||||||
|
if (is_null($constructor))
|
||||||
|
{
|
||||||
|
return new $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dependencies = static::dependencies($constructor->getParameters());
|
||||||
|
|
||||||
|
return $reflector->newInstanceArgs($dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve all of the dependencies from the ReflectionParameters.
|
||||||
|
*
|
||||||
|
* @param array $parameterrs
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function dependencies($parameters)
|
||||||
|
{
|
||||||
|
$dependencies = array();
|
||||||
|
|
||||||
|
foreach ($parameters as $parameter)
|
||||||
|
{
|
||||||
|
$dependency = $parameter->getClass();
|
||||||
|
|
||||||
|
// If the class is null, it means the dependency is a string or some other
|
||||||
|
// primitive type, which we can not esolve since it is not a class and
|
||||||
|
// we'll just bomb out with an error since we have nowhere to go.
|
||||||
|
if (is_null($dependency))
|
||||||
|
{
|
||||||
|
throw new Exception("Unresolvable dependency resolving [$parameter].");
|
||||||
|
}
|
||||||
|
|
||||||
|
$dependencies[] = static::resolve($dependency->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (array) $dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue