framework/di/Container.php
public function get($class, $params = [], $config = [])
    {
        if (isset($this->_singletons[$class])) {
            // singleton
            return $this->_singletons[$class];
        } elseif (!isset($this->_definitions[$class])) {
            return $this->build($class, $params, $config);
        }

        $definition = $this->_definitions[$class];

        if (is_callable($definition, true)) {
            $params = $this->resolveDependencies($this->mergeParams($class, $params));
            $object = call_user_func($definition, $this, $params, $config);
        } elseif (is_array($definition)) {
            $concrete = $definition['class'];
            unset($definition['class']);

            $config = array_merge($definition, $config);
            $params = $this->mergeParams($class, $params);

            if ($concrete === $class) {
                $object = $this->build($class, $params, $config);
            } else {
                $object = $this->get($concrete, $params, $config);
            }
        } elseif (is_object($definition)) {
            return $this->_singletons[$class] = $definition;
        } else {
            throw new InvalidConfigException('Unexpected object definition type: ' . gettype($definition));
        }

        if (array_key_exists($class, $this->_singletons)) {
            // singleton
            $this->_singletons[$class] = $object;
        }

        return $object;
    }
public function get($class, $params = [], $config = [])
    {
        if (isset($this->_singletons[$class])) {
            // singleton
            return $this->_singletons[$class];
        } elseif (!isset($this->_definitions[$class])) {
            return $this->build($class, $params, $config);
        }

        $definition = $this->_definitions[$class];

        if (is_callable($definition, true)) {
            $params = $this->resolveDependencies($this->mergeParams($class, $params));
            $object = call_user_func($definition, $this, $params, $config);
        } elseif (is_array($definition)) {
            $concrete = $definition['class'];
            unset($definition['class']);

            $config = array_merge($definition, $config);
            $params = $this->mergeParams($class, $params);

            if ($concrete === $class) {
                $object = $this->build($class, $params, $config);
            } else {
                $object = $this->get($concrete, $params, $config);
            }
        } elseif (is_object($definition)) {
            return $this->_singletons[$class] = $definition;
        } else {
            throw new InvalidConfigException('Unexpected object definition type: ' . gettype($definition));
        }

        if (array_key_exists($class, $this->_singletons)) {
            // singleton
            $this->_singletons[$class] = $object;
        }

        return $object;
    }
Returns an instance of the requested class.

You may provide constructor parameters (`$params`) and object configurations (`$config`)
that will be used during the creation of the instance.

If the class implements [[\yii\base\Configurable]], the `$config` parameter will be passed as the last
parameter to the class constructor; Otherwise, the configuration will be applied *after* the object is
instantiated.

Note that if the class is declared to be singleton by calling [[setSingleton()]],
the same instance of the class will be returned each time this method is called.
In this case, the constructor parameters and object configurations will be used
only if the class is instantiated the first time.

@param string $class the class name or an alias name (e.g. `foo`) that was previously registered via [[set()]]
or [[setSingleton()]].
@param array $params a list of constructor parameter values. The parameters should be provided in the order
they appear in the constructor declaration. If you want to skip some parameters, you should index the remaining
ones with the integers that represent their positions in the constructor parameter list.
@param array $config a list of name-value pairs that will be used to initialize the object properties.
@return object an instance of the requested class.
@throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition
@throws NotInstantiableException If resolved to an abstract class or an interface (since 2.0.9)