         }
     }
 
+    /// Resolves an object with registered protocol resolvers.
+    /// The implementation checks conformance of an object to all registered protocols and run resolvers for appropriate ones.
+    /// It resolves using a parent container if present, then using its own registered resolvers.
+    /// - parameter object: an object to resolve protocols.
+    /// - note:
+    ///
+    ///       container.resolve(object)
     public func resolve(_ object: Any?) {
         guard let object = object else { return }
 

    private var protocolResolvers: [ProtocolResolver] = []
    private var typeResolvers: [String: TypeResolver] = [:]

    public init(parentContainer: DependencyInjectionContainer? = nil) {
        self.parentContainer = parentContainer
    }

        }
    }

    /// Returns a string representation of a type.
    /// - parameter type: an object type.
    /// - returns: a string representation of a type. For example, `Module.Type.NestedType`.
    private func key<D>(_ type: D.Type) -> String {
        return String(reflecting: type)
    }

    /// Registers a type resolver.
    /// - parameter resolver: a function that returns an object of type D.
    /// - note:
    ///
    ///       let dependency: Dependency = MyDependency()
    ///       let container = Odin()
    ///       container.register { () -> Dependency in
    ///           return dependency
    ///       }
    public func register<D>(_ resolver: @escaping () -> D) {
        typeResolvers[key(D.self)] = resolver
    }

    /// Resolves a registered type.
    /// Checks and run a resolver for a given type.
    /// - returns: a registered object for a given type.
    /// - note:
    ///
    ///       let dependency: Dependency? = container.resolve()
    public func resolve<D>() -> D? {
        return typeResolvers[key(D.self)]?() as? D ?? parentContainer?.resolve()
    }
