      - parameter instance: The instance to register.
      
      - note: The `ignored` parameter is used to disambiguate an overload. Otherwise, the compiler can't figure out
-     whether Guise is registering an instance or a registration block.
+     whether Guise is registering an instance or a block.
     */
     public static func register<T>(instance: T, ignored: Int = 0) -> Key {
         return register(key: Key(type: T.self, name: Name.default, container: Name.default), cached: true) { instance }
     }
     
+    /**
+     Resolve a dependency registered with the given key.
+     
+     - returns: The registered dependency or `nil` if it is not found.
+     
+     - parameters:
+        - key: The key to resolve.
+        - parameter: A parameter to pass to the resolution block.
+        - cached: Whether to use the cached value or to call the block again.
+     
+     Passing `nil` for the `cached` parameter causes Guise to use the value of `cached` recorded
+     when the dependency was registered. In most cases, this is what you want.
+    */
     public static func resolve<T>(key: Key, parameter: Any = (), cached: Bool? = nil) -> T? {
         guard let dependency = lock.read({ registrations[key] }) else { return nil }
-        return dependency.resolve(parameter: parameter, cached: cached ?? dependency.cached)
-    }
-    
+        return dependency.resolve(parameter: parameter, cached: cached)
+    }
+    
+    /**
+     Resolve a dependency registered with the given key.
+     
+     - returns: The registered dependency or `nil` if it is not found.
+     
+     - parameters:
+         - key: The key to resolve.
+         - parameter: A parameter to pass to the resolution block.
+         - cached: Whether to use the cached value or to call the block again.
+     
+     Passing `nil` for the `cached` parameter causes Guise to use the value of `cached` recorded
+     when the dependency was registered. In most cases, this is what you want.
+    */
     public static func resolve<T, N: Hashable, C: Hashable>(name: N, container: C, parameter: Any = (), cached: Bool? = nil) -> T? {
         return resolve(key: Key(type: T.self, name: name, container: container), parameter: parameter, cached: cached)
     }
     
+    /**
+     Resolve a dependency registered with the given type `T` and `name`.
+     
+     - returns: The registered dependency or `nil` if it is not found.
+     
+     - parameters:
+         - name: The name under which the block was registered.
+         - parameter: A parameter to pass to the resolution block.
+         - cached: Whether to use the cached value or to call the block again.
+     
+     Passing `nil` for the `cached` parameter causes Guise to use the value of `cached` recorded
+     when the dependency was registered. In most cases, this is what you want.
+    */
     public static func resolve<T, N: Hashable>(name: N, parameter: Any = (), cached: Bool? = nil) -> T? {
         return resolve(key: Key(type: T.self, name: name, container: Name.default), parameter: parameter, cached: cached)
     }
-    
+
+    /**
+     Resolve a dependency registered with the given type `T` in the given `container`.
+     
+     - returns: The registered dependency or `nil` if it is not found.
+     
+     - parameters:
+         - container: The key to resolve.
+         - parameter: A parameter to pass to the resolution block.
+         - cached: Whether to use the cached value or to call the block again.
+     
+     Passing `nil` for the `cached` parameter causes Guise to use the value of `cached` recorded
+     when the dependency was registered. In most cases, this is what you want.
+    */
     public static func resolve<T, C: Hashable>(container: C, parameter: Any = (), cached: Bool? = nil) -> T? {
         return resolve(key: Key(type: T.self, name: Name.default, container: container), parameter: parameter, cached: cached)
     }
-    
+
+    /**
+     Resolve a registered dependency.
+     
+     - returns: The registered dependency or `nil` if it is not found.
+     
+     - parameters:
+         - parameter: A parameter to pass to the resolution block.
+         - cached: Whether to use the cached value or to call the block again.
+     
+     Passing `nil` for the `cached` parameter causes Guise to use the value of `cached` recorded
+     when the dependency was registered. In most cases, this is what you want.
+    */
     public static func resolve<T>(parameter: Any = (), cached: Bool? = nil) -> T? {
         return resolve(key: Key(type: T.self, name: Name.default, container: Name.default), parameter: parameter, cached: cached)
     }

        - container: The container in which to register the block.
        - cached: Whether or not to cache the result of the registration block.
        - registration: The block to register with Guise.
    */
    public static func register<P, T, N: Hashable, C: Hashable>(name: N, container: C, cached: Bool = false, registration: @escaping Registration<P, T>) -> Key {
        return register(key: Key(type: T.self, name: name, container: container), cached: cached, registration: registration)

    private static var lock = Lock()
    private static var registrations = [Key: Dependency]()
    
    private static func register<P, T>(key: Key, cached: Bool = false, registration: @escaping Registration<P, T>) -> Key {
        lock.write { registrations[key] = Dependency(cached: cached, registration: registration) }
        return key
    }
    
    /**
     Register the `registration` block with the type `T` in the given `name` and `container`.
     
     - returns: The unique `Key` for this registration.
     
