publicfunctioninstance($abstract, $instance)
{$this->removeAbstractAlias($abstract);
$isBound = $this->bound($abstract);
unset($this->aliases[$abstract]);
// We'll check to determine if this type has been bound before, and if it has// we will fire the rebound callbacks registered with the container and it// can be updated with consuming classes that have gotten resolved here.$this->instances[$abstract] = $instance;
if ($isBound) {
$this->rebound($abstract);
}
return$instance;
}
publicfunctionbind($abstract, $concrete = null, $shared = false)
{// If no concrete type was given, we will simply set the concrete type to the // abstract type. After that, the concrete type to be registered as shared // without being forced to state their classes in both of the parameters$this->dropStaleInstances($abstract);
if (is_null($concrete)) {
$concrete = $abstract;
}
// If the factory is not a Closure, it means it is just a class name which is// bound into this container to the abstract type and we will just wrap it// up inside its own Closure to give us more convenience when extending.if (! $concreteinstanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
// If the abstract type was already resolved in this container we'll fire the// rebound listener so that any objects which have already gotten resolved// can have their copy of the object updated via the listener callbacks.if ($this->resolved($abstract)) {
$this->rebound($abstract);
}
}
protectedfunctionresolve($abstract, $parameters = [])
{$abstract = $this->getAlias($abstract);
$needsContextualBuild = ! empty($parameters) || ! is_null($this->getContextualConcrete($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 timeif (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
return$this->instances[$abstract];
}
$this->with[] = $parameters;
$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);
} else {
$object = $this->make($concrete);
}
// If we defined any extenders for this type, we'll need to spin through them// and apply them to the object being built. This allows for the extension// of services, such as changing configuration or decorating the objectforeach ($this->getExtenders($abstract) as$extender) {
$object = $extender($object, $this);
}
// 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) && ! $needsContextualBuild) {
$this->instances[$abstract] = $object;
}
$this->fireResolvingCallbacks($abstract, $object);
// Before returning, we will also set the resolved flag to "true" and pop off// the parameter overrides for this build. After those two things are done// we will be ready to return back the fully constructed class instance.$this->resolved[$abstract] = true;
array_pop($this->with);
}
protectedfunctiongetConcrete($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 automaticallyif (isset($this->bindings[$abstract])) {
return$this->bindings[$abstract]['concrete'];
}
return$abstract;
}
publicfunctionbuild($concrete)
{// 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 fro more fine-tuned resolution of these objects.if ($concrete instance of Closure) {
return$concrete($this, $this->getLastParameterOverride());
}
$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 abstraction so we need to bail outif (! $reflector->isInstantiable()) {
return$this->noInstantiable($concrete);
}
$this->buildStack[] = $concrete;
$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)) {
array_pop($this->buildStack);
returnnew$concrete;
}
$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$instances = $this->resolveDependencies($dependencies);
array_pop($this->buildStack);
return$reflector->newInstanceArgs($instances);
}
protectedfunctionresolveDependencies(array $dependencies)
{$results = [];
foreach ($dependenciesas$dependency) {
// If this dependency has a override for this particular build we will use// that instead as the value. Otherwise, we will continue with this run// of resolutions and let reflection attempt to determine the result.if ($this->hasParameterOverride($dependency)) {
$results[] = $this->getParameterOverride($dependency);
continue;
}
// If the class is null, it means the dependency is a string or some other// primitive type which we cannot resolve since it is not a class and// we will just bomb out with an error since we have no-where to go.
results[] = is_null($dependency->getClass()) ? $this->resolvePrimitive($dependency) : $this->resolveClass($dependency);
}
return$results;
}
protectedfunctionresolveClass(ReflectionParameter $parameter)
{try {
return$this->make($parameter->getClass()->name);
}
// If we cannot resolve the class instance, we will check if the value// is optional, and if it is we will return the optional parameter value as// the value of the dependency, similarly to how we do this scalars.catch (BindingResolutionException $e) {
if ($parameter->isOptional()) {
return$parameter->getDefaultValue;
}
throw$e;
}
}