Fetches an instance or creates one using the registered factory method
        :argument key the key to look up
        :return the created or looked up instance

def resolve(self, key: Any) -> Any:
        """
        Fetches an instance or creates one using the registered factory method
        :argument key the key to look up
        :return the created or looked up instance
        """
        if key not in self._singletons:
            # if registered, determine if the result will be shared
            if key in self._factories:
                factory = self._factories[key]
                result = factory(self)
                if isinstance(factory, SingletonFactory):
                    self._singletons[key] = result
                return result
            # if not registered, try to automatically resolve it based on
            # its annotations. Automatically resolved keys are always shared
            elif isinstance(type(key), type):
                result = self._resolve_class(key)
                self._singletons[key] = result
                return result
            else:
                msg = 'Unable to resolve factory for key %s' % key
                raise ResolveException(msg)
        else:
            return self._singletons[key]