Register a binding with the container.

@param  string|array          $abstract
@param  \Closure|string|null  $concrete
@param  bool                  $shared
498373
public function bind($abstract, $concrete = null, $shared = false)
    {
        $this->app->bind($abstract, $concrete, $shared);
    }
80155
public function bind($abstract, $concrete = null, $singleton = false)
    {
        if (is_array($abstract)) {
            list($abstract, $alias) = [key($abstract), current($abstract)];
            $this->alias($abstract, $alias);
        }

        $abstract = $this->filter($abstract);
        $concrete = $this->filter($concrete);

        if (is_null($concrete)) {
            $concrete = $abstract;
        }

        $this->binds[$abstract] = compact('concrete', 'singleton');
        return $this;
    }
629937
protected function registerBindings()
    {
        foreach ($this->bindings as $concrete => $abstracts) {
            if (!is_array($abstracts)) {
                $this->app->bind($abstracts, $concrete);
                continue;
            }

            $first = array_shift($abstracts);

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

            foreach ($abstracts as $abstract) {
                $this->app->alias($first, $abstract);
            }
        }
    }
999562
protected function isShared($abstract)
    {
        $abstract = $this->normalize($abstract);
        //存在实列集合中， 肯定是共享的
        if (isset($this->instances[$abstract])) {
            return true;
        }
        if (! isset($this->bindings[$abstract]['shared'])) {
            return false;
        }
        return $this->bindings[$abstract]['shared'] === true;
    }
511711
public function bind($id, $concrete = null, $shared = false)
    {
        if (null === $concrete) {
            $concrete = $id;
        }

        $id = $this->normalizeString($id);

        //if its an instance save is as shared regardless of variable
        if (is_object($concrete) && !$concrete instanceof \Closure) {
            //apply any extenders - may not be that useful with an instance but hey ho.
            $instance = $this->applyExtenders($id, $concrete);
            $this->sharedInstances[$id] = $instance;
            return;
        }

        $concrete = $this->normalizeString($concrete);

        //if its callable, or is array and first item is callable
        if (is_callable($concrete) || (is_array($concrete) && is_callable($concrete[0]))) {
            if (false === $shared) {
                $this->definitions[$id] = (array) $concrete;
                return;
            }
            $this->sharedDefinitions[$id] = (array) $concrete;
            return;
        }

        //if its a class string and it exists, or its an array and the first item is a class string
        if (is_string($concrete) && class_exists($concrete) || (is_array($concrete) && class_exists($concrete[0]))) {
            if (false === $shared) {
                $this->definitions[$id] = (array) $concrete;
                return;
            }
            $this->sharedDefinitions[$id] = (array) $concrete;
            return;
        }

        //if were here its arbitary data to assign on the container
        $this->sharedInstances[$id] = $concrete;
    }
221303
public function instance($abstract, $instance)
    {
        $this->sharedInstances[$abstract] = $instance;

        // This will never be called, but makes resolved, bound etc. easier
        $this->storeBinding($abstract, function ($container) use ($instance) {
            return $instance;
        }, true);

        $this->callAllListeners($abstract, $instance);

        return $this;
    }
568918
public function when($concrete)
    {
        $aliases = [];

        foreach (Arr::wrap($concrete) as $c) {
            $aliases[] = $this->getAlias($c);
        }

        return new ContextualBindingBuilder($this, $aliases);
    }
150859
protected function storeBinding($abstract, $concrete, $shared)
    {
        $this->bindings[$abstract] = [
            'concrete' => $this->checkAndReturnCallable($concrete),
            'shared'   => $shared,
        ];

        return $this;
    }
1344404
public function register(array $concreteConfig, $uniqueId)
    {
        $concreteConfig = $this->parseWithDefaultStructure($concreteConfig);

        if (!Validator::okayToRegister($uniqueId, $concreteConfig, $this->defaultStructure, __CLASS__)) {
            return false;
        }

        $concrete = $this->getConcrete($concreteConfig, $uniqueId);

        if (true === $this->skipQueue) {
            return $this->registerConcrete($concrete, $uniqueId);
        }

        return $this->queued[$uniqueId] = $concrete;
    }
527564
protected function getClosure($abstract, $concrete)
    {
        return function (Container $container, $parameters = []) use ($abstract, $concrete) {
            if ($abstract == $concrete) {
                return $container->build($concrete);
            }

            return $container->make($concrete, $parameters);
        };
    }
742055
public function share(string $id, $concrete = null) : DefinitionInterface
    {
        return $this->add($id, $concrete, true);
    }
1351031
public function resolve($binding, $alias = true)
    {
        $this->registerProvidersFor($binding);

        $rawObject = $this->getRaw($binding);

        // If the abstract is not registered, do it now for easy resolution.
        if (is_null($rawObject)) {
            // Pass $binding to both so it doesn't need to check if null again.
            $this->bind($binding, $binding);

            $rawObject = $this->getRaw($binding);
        }

        if ($alias and isset($this->aliases[$binding])) {
            return $this->resolve($this->aliases[$binding], false);
        }

        return $rawObject($this);
    }
235573
public function createInstance($reference, array $parameters = [], $shared = true)
    {
        $reference = $this->mapReference($reference);

        //if we have already created this reference;
        if (isset($this[$reference])) {
            return $this[$reference];
        }

        //check if $reference is already bound and return if is instance;
        $class = new ReflectionClass($reference);

        //Check that we can instantiate this class;
        if (!$class->isInstantiable()) {
            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not instantiable.', $reference));
        }

        //Wrap the call function in a lamda;
        $callable = $this->wrapInCallable($class, $parameters);

        //if instance is defined and is instance wrap in closure and return;
        return ($shared)
            ? $this->createSharedReference($reference, $callable)
            : $this->createReference($reference, $callable);

    }
788836
public function bind($id, $concrete, $singleton = false)
    {

        $concrete = $concrete ?: $id;

        if (!$concrete instanceof Closure) {
            
            // If the factory (resolver) is NOT a closure we assume,
            // that it is a classname and wrap it into a closure so it' s
            // easier when resolving.

            $concrete = function (Container $container) use ($id, $concrete) {

                $method = ($id == $concrete) ? 'build' : 'resolve';

                return $container->$method($concrete, array());
            };
        }


        $this->binds[$id] = compact('concrete', 'singleton');
    }
289305
public function set($name, $definition, $shared = true)
    {
        if (true === $this->has($name)) {
            throw new Exception('Service "' . $name . '" already registered');
        }

        switch (true) {
            case is_array($definition):
                $provider = new ServiceProvider($definition);
                $provider->register($name, $this);
                break;

            default:
                $this->payload[$name] = new Factory($this, $definition, $shared);
                $this->payload[$name]->setName($name);
        }

        return $this;
    }
1185074
public function bindForCallback(string $abstract, $concrete, callable $callback)
    {
        $hasOriginal      = $this->container->bound($abstract);
        $originalInstance = false;

        if ($hasOriginal) {
            $binding = $this->container->getBindings()[$abstract] ?? null;

            $hasInstance = $binding && $binding['shared'] && $this->container->resolved($abstract);

            if ($hasInstance) {
                $originalInstance = $this->container->make($abstract);
            }
        }

        $this->container->instance($abstract, $concrete);

        try {
            $return = $callback();
            return $return;
        } finally {
            unset($this->container[$abstract]);

            if ($hasOriginal && (isset($binding) && $binding)) {
                $this->container->bind($abstract, $binding['concrete'], $binding['shared']);

                if ($originalInstance) {
                    $this->container->instance($abstract, $originalInstance);
                }
            }
        }
    }
700712
public function haveContextualBinding($concrete, $abstract, $implementation)
    {
        if (! isset($this->contextualBindings[$concrete])) {
            $this->contextualBindings[$concrete] = [];
        }

        $this->contextualBindings[$concrete][$abstract] = $implementation;
    }