docs: def register(self, function=None, *, singleton=False, threadlocal=False, name=None):
          """
          Add an object to the injector's registry.
  
          Can be used as a decorator like so:
          
          >>> @injector.register
          ... def my_dependency(): ...
  
          or a plain function call by passing in a callable
          injector.register(my_dependency)
  
          :param function: The function or callable to add to the registry
          :param name: Set the name of the dependency. Defaults to the name of `function`
          :param singleton: When True, register dependency as a singleton, this
              means that `function` is called on first use and its 
              return value cached for subsequent uses. Defaults to False
          :param threadlocal: When True, register dependency as a threadlocal singleton,
              Same functionality as ``singleton`` except :class:`Threading.local` is used
              to cache return values.
          :type function: callable
          :type singleton: bool
          :type threadlocal: bool
          :type name: string
          """
          def decorator(function=None):
              self._set(name, function, singleton, threadlocal)
              return function
          if function:
              return decorator(function)
          return decorator