Construct a class and all the dependencies using the reflection library of PHP.

@param string $abstract The class name or container element name to make.

@throws ReflectionException
@return Closure
188909
protected function construct(string $abstract) : Closure
    {
        $inspector = new ReflectionClass($abstract);

        if (($constructor = $inspector->getConstructor()) && ($dependencies = $constructor->getParameters())) {

            // if, and only if, a class has a constructor with parameters, we try to solve then
            // creating a resolving callback that in every call will recalculate all dependencies
            // for the given class, and offcourse, using a cached resolving callback if exists.

            return function (string $abstract, array $parameters) use ($inspector, $dependencies) {
                return $inspector->newInstanceArgs(
                    $this->process($abstract, $parameters, $dependencies)
                );
            };
        }

        return function (string $abstract) {
            return new $abstract;
        };
    }
893486
public static function get($abstract)
    {
        if (!isset(self::getInstance()->containers[$abstract])) {
            try {
                $reflect = new ReflectionClass(self::getInstance()->bind[$abstract]);
            } catch (ReflectionException $e) {
                throw new ContainerException('Cannot find "' . $abstract . '" in container');
            }

            self::set($abstract, $reflect->newInstanceArgs([]));
        }

        return self::getInstance()->containers[$abstract];
    }
919736
public function resolving($abstract, Closure $callback = null)
	{
		if ($callback === null && $abstract instanceof Closure)
		{
			$this->resolvingCallback($abstract);
		}
		else
		{
			$this->resolvingCallbacks[$abstract][] = $callback;
		}
	}
730373
public static function buildClass( $class, array $parameters = [] )
	{
		if ( !is_string( $class ) )
			throw new BindingException( "Class must be a string" );

		if ( static::building( $class ) )
			throw new BindingException( "The class [" . $class . "] is already being built." );

		static::$buildStack[] = $class;

		try
		{
			$reflector = new \ReflectionClass( $class );

			// 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 abstractions so we need to bail out.
			if ( !$reflector->isInstantiable() )
				throw new BindingException( "Target [$class] is not instantiable." );

			$constructor = $reflector->getConstructor();

			// If there are no constructors, that means there are no dependencies then
			// we can just resolve the instances of the objects right away.
			if ( is_null( $constructor ) )
				return new $class;

			$dependencies = $constructor->getParameters();

			// Once we have all the constructor's parameters we can create each of the
			// dependency instances and then use the reflection instances to make a
			// new instance of this class, injecting the created dependencies in.
			$parameters = static::keyParametersByArgument( $dependencies, $parameters );

			$instances = static::getDependencies( $dependencies, $parameters, $class );

			array_pop( static::$buildStack );

			/**/

			return $reflector->newInstanceArgs( $instances );
		}
		catch ( \ReflectionException $e )
		{
			array_pop( static::$buildStack );

			throw new BindingException( "Failed to build [$class]: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() );
		}
	}
877058
public function bind($abstract, $concrete = null, $shared = false)
    {
        if ($concrete == null) {
            $concrete = $abstract;
        }

        if ( ! ($concrete instanceof Closure)) {
            $concrete = function ($container, $args = []) use ($abstract, $concrete) {
                $method = ($abstract == $concrete || is_object($concrete)) ? 'build' : 'make';
                return $container->$method($concrete, $args);
            };
        }

        $this->bindings[$abstract] = [
            'concrete' => $concrete,
            'shared' => $shared
        ];
    }
945151
public function makeModel($abstract)
    {
        if (isset($this->Mo[$abstract])) {
            return $this->Mo[$abstract];
        }
        if(!class_exists($abstract)){
            //没有找到执行方法
            //执行404;
            echo '<br>Miss file : <br>';
            echo $abstract;
            D();
        }
        //检查类文件是否存在
        $this->Mo[$abstract] = new $abstract();     //模型存储

        return $this->Mo[$abstract];
    }
914586
protected function resolve($abstract, array $parameters = [])
    {
        if ($this->bound($abstract)) {
            array_unshift($parameters, $this);

            return call_user_func_array($this->bindings[$abstract]['concrete'], $parameters);
        }

        $reflector = new ReflectionClass($abstract);

        if (!$constructor = $reflector->getConstructor()) {
            return new $abstract($parameters);
        }

        $constructorParams = $constructor->getParameters();

        $callParams = [];

        foreach ($constructorParams as $param) {
            if ($param->getClass()) {
                $callParams[] = $this->__invoke($param->getClass()->getName());
            }
        }

        foreach ($parameters as $key => $value) {
            $callParams[] = $value;
        }

        return $reflector->newInstanceArgs($callParams);
    }
491612
public function resolveClosure(Closure $closure, array $args = [])
    {
        $closureRef = new ReflectionFunction($closure);
        $dependencies = $this->getMethodDependencies($closureRef, $args);

        return $closureRef->invokeArgs($dependencies);
    }
798951
public function build($concrete, $parameters = array())
	{
		// If the concrete type is actually a Closure, we will just execute it and
		// hand back the results of the functions, which allows functions to be
		// used as resolvers for more fine-tuned resolution of these objects.
		if ($concrete instanceof Closure)
		{
			return $concrete($this, $parameters);
		}

		$reflector = new ReflectionClass($concrete);

		// 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 abstractions so we need to bail out.
		if ( ! $reflector->isInstantiable())
		{
			$message = "Target [$concrete] is not instantiable.";

			throw new BindingResolutionException($message);
		}

		$constructor = $reflector->getConstructor();

		// If there are no constructors, that means there are no dependencies then
		// we can just resolve the instances of the objects right away, without
		// resolving any other types or dependencies out of these containers.
		if (is_null($constructor))
		{
			return new $concrete;
		}

		$classes = $constructor->getParameters();

		// Once we have all the constructor's parameters we can create each of the
		// dependency instances and then use the reflection instances to make a
		// new instance of this class, injecting the created dependencies in.
		$deps = array_merge($parameters, $this->getDependencies(
			array_diff_key($classes, $parameters)
		));

		return $reflector->newInstanceArgs($deps);
	}
1135317
protected function getConcrete($abstract)
	{
		if ( ! is_null($concrete = $this->getContextualConcrete($abstract)))
		{
			return $concrete;
		}

		// If we don't have a registered resolver or concrete for the type, we'll just
		// assume each type is a concrete name and will attempt to resolve it as is
		// since the container should be able to resolve concretes automatically.
		if ( ! isset($this->bindings[$abstract]))
		{
			if ($this->missingLeadingSlash($abstract) &&
				isset($this->bindings['\\'.$abstract]))
			{
				$abstract = '\\'.$abstract;
			}

			return $abstract;
		}

		return $this->bindings[$abstract]['concrete'];
	}
1072682
protected function getExtender($abstract, Closure $closure)
    {
        // To "extend" a binding, we will grab the old "resolver" Closure and pass it
        // into a new one. The old resolver will be called first and the result is
        // handed off to the "new" resolver, along with this container instance.
        $resolver = $this->bindings[$abstract]['concrete'];

        return function($container) use ($resolver, $closure)
        {
            return $closure($resolver($container), $container);
        };
    }
1054861
protected function convertParameters($abstract, array $parameters)
    {

        // TODO Ugly hack to get the concrete class in laravel
        $concrete = Cheat::call($this->laravel, 'getConcrete', [$abstract]);

        if ($concrete instanceof Closure) {
            return $parameters;
        }

        $constructor = (new ReflectionClass($concrete))->getConstructor();

        $named = [];

        foreach ($constructor->getParameters() as $i=>$parameter) {
            if (isset($parameters[$i])) {
                $named[$parameter->getName()] = $parameters[$i];
            }
        }

        return $named;

    }
567346
private function __reflection()
    {
        if (!$this->__reflection) {
            $this->__reflection = new \ReflectionClass(get_class($this));
        }
        return $this->__reflection;
    }
1153892
public function createInstance(string $class)
    {
        $refClass = new \ReflectionClass($class);
        $args = [];
        if ($refClass->getConstructor()) {
            foreach ($refClass->getConstructor()->getParameters() as $parameter) {
                $name = Inflector::tableize(str_replace('_', '.', $parameter->getName()));
                $dependency = null;
                if ($parameter->getClass()) {
                    if ($this->container->has($parameter->getClass()->getName())) {
                        $dependency = $this->container->get($parameter->getClass()->getName());
                    } elseif ($this->container->has($name)) {
                        $dependency = $this->container->get($name);
                    }
                } elseif ($this->container->hasParameter($name)) {
                    $dependency = $this->container->getParameter($name);
                }
                $args[] = $dependency;
            }
        }

        return $refClass->newInstanceArgs($args);
    }
1301094
public function get($abstract)
    {
        /**
         * @todo validate that $abstract is a string
         */

        if (!isset($this->definitions[$abstract])) {

            $this->definitions[$abstract] = new Definition($this);
        }

        return $this->definitions[$abstract];
    }
641930
public function singleton(string $abstract, $concrete = null, array $arguments = []): self
    {
        $this->data->singleton($abstract, $concrete, $arguments);
        return $this;
    }
1084481
public function build($concrete, $parameters = array())
        {
            // If the concrete type is actually a Closure, we will just execute it and
            // hand back the results of the functions, which allows functions to be
            // used as resolvers for more fine-tuned resolution of these objects.
            if ($concrete instanceof \Closure) {
                return $concrete($this, $parameters);
            }

            $reflector = new \ReflectionClass($concrete);

            // 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 abstractions so we need to bail out.
            if (!$reflector->isInstantiable()) {
                $message = "Target [$concrete] is not instantiable.";

                throw new Exception($message);
            }

            $constructor = $reflector->getConstructor();

            // If there are no constructors, that means there are no dependencies then
            // we can just resolve the instances of the objects right away, without
            // resolving any other types or dependencies out of these containers.
            if (is_null($constructor)) {
                return new $concrete;
            }

            $parameters = $constructor->getParameters();

            // Once we have all the constructor's parameters we can create each of the
            // dependency instances and then use the reflection instances to make a
            // new instance of this class, injecting the created dependencies in.
            $dependencies = $this->getDependencies($parameters);

            return $reflector->newInstanceArgs($dependencies);
        }