Skip to content

Instantly share code, notes, and snippets.

@agiokas
Created March 23, 2021 22:00
Show Gist options
  • Select an option

  • Save agiokas/3b422d25b20e16c6b95d000417e7be2a to your computer and use it in GitHub Desktop.

Select an option

Save agiokas/3b422d25b20e16c6b95d000417e7be2a to your computer and use it in GitHub Desktop.
//
// Created by Apostolos Giokas on 10.03.21.
//
import Foundation
private protocol ICreator {
var identifier: ObjectIdentifier { get }
func create(for: Any) -> Any?
}
protocol IFactory {
associatedtype Return
func create(for object: Any) -> Return?
func register<T>(for type: T.Type, factory: @escaping (T) -> Return)
}
open class Factory<Return>: IFactory {
private var items = [ObjectIdentifier: ICreator]()
public init() {}
public func register<T>(for type: T.Type, factory: @escaping (T) -> Return) {
items[ObjectIdentifier(type)] = Creator<T>(for: type, factory: factory)
}
public func create(for object: Any) -> Return? {
let resolver = items[ObjectIdentifier(type(of: object))]
return resolver?.create(for: object) as? Return
}
private class Creator<Input>: ICreator {
let factory: (Input) -> Return
let identifier: ObjectIdentifier
let type: Input.Type
init(for type: Input.Type, factory: @escaping (Input) -> Return) {
self.factory = factory
self.type = type
identifier = ObjectIdentifier(type)
}
func create(for object: Any) -> Any? {
guard let someVM = object as? Input else { return nil }
return factory(someVM)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment