/**
  * {@inheritdoc}
  */
 public function log(BoundDefinition $definition, array $params, array $setters, $instance, Bind $bind)
 {
     if ($instance instanceof DependencyProvider) {
         $this->buildProvider($instance);
         return;
     }
     $this->logger->log($definition, $params, $setters, $instance, $bind);
     $this->build($definition->class, $instance, $params, $setters, $definition->isSingleton);
 }
 /**
  * @param string $target interface name
  *
  * @return Compiler
  */
 private function getProvidedInstance($target)
 {
     $provider = $this->injector->getInstance($target);
     /** @var $provider ProviderInterface */
     $instance = $provider->get();
     if ($this->logger) {
         $dependencyProvider = new DependencyProvider($provider, $instance);
         $definition = new BoundDefinition();
         $definition->class = $target;
         $this->logger->log($definition, [], [], $dependencyProvider, new Bind());
     }
     return $instance;
 }
 /**
  * {@inheritdoc}
  */
 public function getInstance($class)
 {
     // module activation
     $this->module->activate($this);
     if ($this->boundInstance->hasBound($class, $this->module)) {
         return $this->boundInstance->getBound();
     }
     // get bound config
     $definition = $this->boundInstance->getDefinition();
     // be all parameters ready
     $params = $this->boundInstance->bindConstruct($class, $definition->params, $this->module);
     $refClass = new \ReflectionClass($definition->class);
     if ($refClass->isInterface()) {
         return $this->getInstance($definition->class);
     }
     // weave aspect
     $module = $this->module;
     $bind = $module($definition->class, new $this->bind());
     /* @var $bind \Ray\Aop\Bind */
     $hasBinding = $bind->hasBinding();
     $instance = $hasBinding ? $this->compiler->noBindNewInstance($definition->class, $params, $bind) : $refClass->newInstanceArgs($params);
     // do not call constructor twice. ever.
     unset($definition->setter['__construct']);
     // call setter methods
     foreach ($definition->setter as $method => $value) {
         call_user_func_array([$instance, $method], $value);
     }
     // attach interceptors
     if ($hasBinding) {
         $instance->rayAopBind = $bind;
     }
     // logger inject info
     if ($this->logger) {
         $this->logger->log($definition, $params, $definition->setter, $instance, $bind);
     }
     // object life cycle, store singleton instance.
     $this->postInject($instance, $definition);
     return $instance;
 }