         self.hashValue = hash(self.type, self.name, self.container)
     }
     
-    public let hashValue: Int
-}
-
-public func ==(lhs: Key, rhs: Key) -> Bool {
+    public init<T, N: Hashable>(type: T.Type, name: N) {
+        self.init(type: type, name: name, container: Name.default)
+    }
+    
+    public init<T, C: Hashable>(type: T.Type, container: C) {
+        self.init(type: type, name: Name.default, container: container)
+    }
+}
+
+extension Set where Element == AnyKey {
+    public func typed<T>() -> Set<Key<T>> {
+        return Set<Key<T>>(flatMap{ Key($0) })
+    }
+}
+
+public func ==(lhs: AnyKey, rhs: AnyKey) -> Bool {
     if lhs.hashValue != rhs.hashValue { return false }
     if lhs.type != rhs.type { return false }
     if lhs.name != rhs.name { return false }
+    if lhs.container != rhs.container { return false }
+    return true
+}
+
+public struct Key<T>: Keyed, Hashable {
+    public let type: String
+    public let name: AnyHashable
+    public let container: AnyHashable
+    public let hashValue: Int
+    
+    public init<N: Hashable, C: Hashable>(name: N, container: C) {
+        self.type = String(reflecting: T.self)
+        self.name = name
+        self.container = container
+        self.hashValue = hash(self.type, self.name, self.container)
+    }
+    
+    public init<N: Hashable>(name: N) {
+        self.init(name: name, container: Name.default)
+    }
+    
+    public init<C: Hashable>(container: C) {
+        self.init(name: Name.default, container: container)
+    }
+    
+    public init() {
+        self.init(name: Name.default, container: Name.default)
+    }
+    
+    public init?(_ key: AnyKey) {
+        if key.type != String(reflecting: T.self) { return nil }
+        self.type = key.type
+        self.name = key.name
+        self.container = key.container
+        self.hashValue = hash(self.type, self.name, self.container)
+    }
+    
+}
+
+public func ==<T>(lhs: Key<T>, rhs: Key<T>) -> Bool {
+    if lhs.hashValue != rhs.hashValue { return false }
+    if lhs.name != rhs.name { return false }
+    if lhs.container != rhs.container { return false }
     return true
 }
 

     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)
    }
    
    /**

     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(name: name, container: Name.default), parameter: parameter, cached: cached)
    }

    /**
