public function factory($className, array $params = [])
        {
            $instanceHash = sha1($className . serialize($params));

            // Return already instantiated object instance if set
            if (isset($this->instances[$instanceHash])) {
                return $this->instances[$instanceHash];
            }

            // Return new class instance
            // Reflection is known for incurring overhead - hack to avoid it if we can
            $paramCount = count($params);
            if (0 === $paramCount) {
                $instance = new $className();
            } elseif (1 === $paramCount) {
                $instance = new $className(Arrays::first($params));
            } elseif (2 === $paramCount) {
                $instance = new $className($params[0], $params[1]);
            } elseif (3 === $paramCount) {
                $instance = new $className($params[0], $params[1], $params[2]);
            } else {
                $class = new \ReflectionClass($className);
                $instance = $class->newInstanceArgs($args);
            }

            return $this->setInstance($instanceHash, $instance);
        }