// Paste this code into a Swift playground. // @objc is required for this to work // Try removing @objc and see what happens. @objc protocol ServiceType { func performService() -> String } class ServiceResolver { private init() {} private static var services = [String: Any]() static func resolve(proto: Protocol) -> R { return services[NSStringFromProtocol(proto)]! as! R } static func register(proto: Protocol, instance: Any) { // NSStringFromProtocol works ONLY with Objective-C protocols. services[NSStringFromProtocol(proto)] = instance } } // To conform to an @objc protocol, // a class must descend from NSObject class Service: NSObject, ServiceType { func performService() -> String { return "I'm doing it!" } } // To conform to an @objc protocol, // a class must descend from NSObject class MockService: NSObject, ServiceType { func performService() -> String { return "I'm mocking you!" } } // .self is required here due to a pecularity of Swift. If there's more than one parameter, // you have to use .self ServiceResolver.register(ServiceType.self, instance: MockService()) // We don't need .self here because there's only one parameter, though // you can add it if you wish. let service: ServiceType = ServiceResolver.resolve(ServiceType)