Skip to content

Instantly share code, notes, and snippets.

@lalkrishna
Created January 26, 2021 16:05
Show Gist options
  • Save lalkrishna/f8cb4fb030879305756161480f696116 to your computer and use it in GitHub Desktop.
Save lalkrishna/f8cb4fb030879305756161480f696116 to your computer and use it in GitHub Desktop.
Dependency injection using Property wrappers (like @EnvironmentObject in SwiftUI). Core code from: https://medium.com/@anuragajwani/dependency-injection-in-ios-and-swift-using-property-wrappers-f411117cfdcf
/* SET */
Container.shared.register(type: User.self, User())
Container.shared.set(User(), forKey: "SecondUser")
/* GET */
let sameUser = Container.shared.resolve(User.self)
let secondUser = Container.shared.get("SecondUser", of: User.self)
/* REMOVE */
$user.deregister() // This will remove "User" from factory.
Container.shared.remove("SecondUser") // Remove second user.
// MARK: - Implementation
class Container {
static let shared = Container()
private var factoryDict: [String: () -> Any] = [:]
func register<Service>(type: Service.Type, _ factory: @autoclosure @escaping () -> Service) {
set(factory, forKey: String(describing: type.self))
}
func resolve<Service>(_ type: Service.Type) -> Service {
get(String(describing: type.self), of: type.self)!
}
func deregister<Service>(_ type: Service.Type) {
remove(String(describing: type.self))
}
func set(_ value: @autoclosure @escaping () -> Any, forKey key: String) {
factoryDict[key] = value
}
func get<Service>(_ key: String, of type: Service.Type) -> Service? {
factoryDict[key]?() as? Service
}
func remove(_ key: String) {
factoryDict[key] = nil
}
}
@propertyWrapper
struct Inject<Type> {
var type: Type
init() {
self.type = Container.shared.resolve(Type.self)
}
var wrappedValue: Type {
get { self.type }
mutating set {
self.type = newValue
}
}
var projectedValue: Inject<Type> { return self }
func deregister() {
Container.shared.deregister(Type.self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment