/**
* Register a binding with the container.
* Register a binding with the container.
* @param string|array $abstract
* @param \Closure|string|null $concrete
* @param bool $shared
* @return void
*/
public function bind($abstract, $concrete = null, $shared = false)
{// bind abstract con
$abstract = $this->normalize($abstract);// get the right normalize

$concrete = $this->normalize($concrete);// get the right concrete

// If the given types are actually an array, we will assume an alias is being
// defined and will grab this "real" abstract class name and register this
// alias with the container so that it can be used as a shortcut for it.

// now i say,if they give us a array use a types.
// so we need do something for it,
// if the "real" abstract class name is too long,
// we can use alias to defined the real class name as a shortcut name.

if (is_array($abstract)) {// check the abstract name is a array
list($abstract, $alias) = $this->extractAlias($abstract);// a array one is abstract , other is alias

$this->alias($abstract, $alias);// return the result to the alias.
}

// If no concrete type was given, we will simply set the concrete type to the
// abstract type. This will allow concrete type to be registered as shared
// without being forced to state their classes in both of the parameter.

// i coming ,if never give us a concrete type class, we will use a abstract type.
// so they will be registered as shared .
// no forced to state their classes in both of the parameter
$this->dropStaleInstances($abstract);// then can drop the state Instances.

if (is_null($concrete)) {
$concrete = $abstract;
}// if the concrete is null

// 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 the instance of concrete not a Closure.
// so it means it just a class name be used bound to a container.
// may be it is a abstract type .
// so we can use that self own Closure to wrap it.
// to give us more function when it extending
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}// get the Closure, more like hook

$this->bindings[$abstract] = compact('concrete', 'shared');// a 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 the class name is ready resolved in the container.
// so we will fire the rebound listener .
// so that any objects which have already gotten resolved can have their copy
// via the listener callbacks
if ($this->resolved($abstract)) {// has the resolved
$this->rebound($abstract);// set the rebound
}
}// too long too not simple