绑定一个类到容器
@access public
@param string $abstract 类标识、接口
@param string|\Closure $concrete 要绑定的类或者闭包
@return void
424839
public function bind($abstract, $concrete = null) {
        if (is_array($abstract)) {
            $this->bind = array_merge($this->bind, $abstract);
        } else {
            $this->bind[$abstract] = $concrete;
        }
    }
491299
protected function getConcrete( $abstract ) {

		$concrete = false;
		$abstract = $this->getAbstract( $abstract );

		if ( $this->has( $abstract ) ) {
			$concrete = $this->bindings[ $abstract ]['concrete'];
		}

		return $concrete ?: $abstract;
	}
188841
protected function findInContextualBindings($abstract)
    {
        if (isset($this->contextual[end($this->buildStack)][$abstract])) {
            return $this->contextual[end($this->buildStack)][$abstract];
        }
    }
80291
public function build($concrete, array $parameters = [])
    {
        $object = parent::build($concrete, $parameters);
        if (is_object($object)) {
            if ($object instanceof ApplicationAwareInterface) {
                $object->setApplication($this);
            }

            if ($object instanceof LoggerAwareInterface) {
                $logger = $this->make('log/factory')->createLogger($object->getLoggerChannel());
                $object->setLogger($logger);
            } elseif ($object instanceof PsrLoggerAwareInterface) {
                $logger = $this->make('log/factory')->createLogger(Channels::CHANNEL_APPLICATION);
                $object->setLogger($logger);
            }
        }

        return $object;
    }
1265443
public function resolve($concrete, $params)
    {
        if ($concrete instanceof \Closure) {
            return $concrete($this, $params);
        }
        $reflector = new \ReflectionClass($concrete);
        // check if class is instantiable
        if (!$reflector->isInstantiable()) {
            throw new \Exception("Class {$concrete} is not instantiable", 500);
        }
        // get class constructor
        $constructor = $reflector->getConstructor();
        if (is_null($constructor)) {
            // get new instance from class
            return $reflector->newInstance();
        }
        // get constructor params
        $parameters = $constructor->getParameters();
        $dependencies = $this->getResolveDependencies($parameters, $params);
        // get new instance with dependencies resolved
        return $reflector->newInstanceArgs($dependencies);
    }
1271486
protected function callAllListeners($abstract, $instance)
    {
        $this->callListeners($abstract, $instance, $this->resolvingListeners);
        $this->callListeners($abstract, $instance, $this->resolvedListeners);
    }
1239889
public function make($abstract, $parameters = array())
        {
            $abstract = $this->getAlias($abstract);

            // If an instance of the type is currently being managed as a singleton we'll
            // just return an existing instance instead of instantiating new instances
            // so the developer can keep using the same objects instance every time.
            if (Arrays::exists($abstract, $this->instances)) {
                return $this->instances[$abstract];
            }
            $concrete = $this->getConcrete($abstract);

            // We're ready to instantiate an instance of the concrete type registered for
            // the binding. This will instantiate the types, as well as resolve any of
            // its "nested" dependencies recursively until all have gotten resolved.
            if ($this->isBuildable($concrete, $abstract)) {
                $object = $this->build($concrete, $parameters);
            } else {
                $object = $this->make($concrete);
            }

            // If the requested type is registered as a singleton we'll want to cache off
            // the instances in "memory" so we can return it later without creating an
            // entirely new instance of an object on each subsequent request for it.
            if ($this->isShared($abstract)) {
                $this->instances[$abstract] = $object;
            }

            return $object;
        }
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);
	}
441031
protected function bindSingletons()
    {
        foreach ($this->singletons as $concrete => $abstracts) {
            if (!is_array($abstracts)) {
                $this->app->bind($abstracts, $concrete, true);
                continue;
            }

            $first = array_shift($abstracts);

            $this->app->bind($first, $concrete, true);

            foreach ($abstracts as $abstract) {
                $this->app->alias($first, $abstract);
            }
        }
    }
282971
protected function rebound($abstract)
    {
        //通过给定的抽象类型 - 实例化具体对象
        $instance = $this->make($abstract);
        //当我们在重新绑定实列到容器中时， 可也为每个从新绑定定义回调函数，
        //方便对象在重新绑定回容器时， 对其进行炒作
        foreach ($this->getReboundCallbacks($abstract) as $callback) {
            call_user_func($callback, $this, $instance);
        }
    }
1210130
public function isSingleton(string $abstract) : bool
    {
        if (! $this->has($abstract)) {
            throw new NotFoundException("Element '$abstract' not found");
        }

        return $this->collection[$abstract] instanceof Closure === false;
    }
403933
public function extend($abstract, Closure $closure)
    {
        if (! isset($this->bindings[$abstract])) {
            throw new \InvalidArgumentException("Type {$abstract} is not bound.");
        }

        if (isset($this->instances[$abstract])) {
            $this->instances[$abstract] = $closure($this->instances[$abstract], $this);

            $this->rebound($abstract);
        } else {
            $extender = $this->getExtender($abstract, $closure);

            $this->bind($abstract, $extender, $this->isShared($abstract));
        }
    }
1251428
public function alias(string $alias, string $abstract): void
    {
        if (\array_key_exists($alias, $this->values) || isset($this->factory[$alias])) {
            throw new InvalidArgumentException("Already defined in container: $alias");
        }

        if ($alias === $abstract) {
            throw new InvalidArgumentException('Alias cannot be the same as the original name');
        }

        $this->alias[$alias] = $abstract;

        if (!isset($this->abstractAlias[$abstract])) {
            $this->abstractAlias[$abstract] = [];
        }

        $this->abstractAlias[$abstract][] = $alias;
    }
919736
public function resolving($abstract, Closure $callback = null)
	{
		if ($callback === null && $abstract instanceof Closure)
		{
			$this->resolvingCallback($abstract);
		}
		else
		{
			$this->resolvingCallbacks[$abstract][] = $callback;
		}
	}
177003
public function instance($abstract, $instance)
    {
        $abstract = $this->normalize($abstract);
        if (is_array($abstract)) {
            list($abstract, $alias) = $this->extractAlias($abstract);
            $this->alias($abstract, $alias);
        }
        unset($this->aliases[$abstract]);
        $bound = $this->bound($abstract);

        $this->instances[$abstract] = $instance;
        if ($bound) {
            $this->rebound($abstract);
        }
    }
1227526
protected function resolveClass(string $concrete)
    {
        $resolved   = $this->resolveArguments($this->arguments);
        $reflection = new ReflectionClass($concrete);

        return $reflection->newInstanceArgs($resolved);
    }
320626
protected function resolve( $concrete )
	{
		if( $concrete instanceof Closure ) {
			return $concrete( $this );
		}

		$reflector = new ReflectionClass( $concrete );

		if( !$reflector->isInstantiable() ) {
			return $this->notInstantiable( $concrete );
		}

		if( is_null(( $constructor = $reflector->getConstructor() ))) {
			return new $concrete;
		}

		return $reflector->newInstanceArgs(
			$this->resolveDependencies( $constructor->getParameters() )
		);
	}