public function register($serviceClass): void {
    try {
      $class = new ReflectionClass($serviceClass);
    } catch(ReflectionException $e) {
      throw new RuntimeException('Service class not found', 0, $e);
    }

    if(!$class->implementsInterface(ServiceProvider::class)) {
      throw new InvalidArgumentException("[$serviceClass] is not a service provider");
    }

    if($class->hasConstant('requires')) {
      $requirements = array_flip($class->getConstant('requires'));

      foreach($this->services as $service_name => $service) {
        if(array_key_exists($service_name, $requirements)) {
          unset($requirements[$service_name]);
        }
      }

      if(count($requirements) !== 0) {
        $this->queue[$serviceClass] = array_flip($requirements);
        return;
      }
    }

    $service = $this->ioc->make($serviceClass);
    $service->register();

    if(!$class->hasConstant('provides')) {
      $this->services[] = $service;
    } else {
      $provides = $class->getConstant('provides');

      $this->services[$provides] = $service;

      foreach($this->queue as $queued_name => &$queued) {
        if(in_array($provides, $queued, true)) {
          unset($this->queue[$queued_name]);
          $this->register($queued_name);
        }
      }
    }
  }