Skip to content

Instantly share code, notes, and snippets.

@fmo91
Last active November 1, 2019 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fmo91/2d359f82569dda69002784a49486b3c8 to your computer and use it in GitHub Desktop.
Save fmo91/2d359f82569dda69002784a49486b3c8 to your computer and use it in GitHub Desktop.
Simple Dependency Injection using @propertyWrapper
import UIKit
enum Dependencies {
struct Name {
let rawValue: String
static let `default` = Name(rawValue: "__default__")
}
final class Container {
private var dependencies: [(key: Dependencies.Name, value: Any)] = []
static let `default` = Container()
func register(_ dependency: Any, for key: Dependencies.Name = .default) {
dependencies.append((key: key, value: dependency))
}
func resolve<T>(_ key: Dependencies.Name = .default) -> T {
return (dependencies
.filter { (dependencyTuple) -> Bool in dependencyTuple.key.rawValue == key.rawValue && dependencyTuple.value is T }
.first)?.value as! T
}
}
@propertyWrapper
struct Inject<T> {
private let dependencyName: Name
private let container: Container
var wrappedValue: T {
get { container.resolve(dependencyName) }
}
init(_ dependencyName: Name = .default, on container: Container = .default) {
self.dependencyName = dependencyName
self.container = container
}
}
}
protocol NameFormatterType {
func format(name: String) -> String
}
struct SirFormatter: NameFormatterType {
func format(name: String) -> String {
"Sir \(name)"
}
}
Dependencies.Container.default.register(SirFormatter())
struct Person {
@Dependencies.Inject() private var nameFormatter: NameFormatterType
let name: String
init(name: String) {
self.name = name
}
func present() {
print(nameFormatter.format(name: name))
}
}
let person = Person(name: "Fernando")
person.present() // Sir Fernando
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment