Hi,
I was playing around with a simple Dependency Injection / Service Locator setup, but couldn't quite understand why the following code only compiles when Inject.wrappedValue.set is enabled?
At first, I didn't see a need to store the injected value in the property, so the original implementation of the getter was just reaching into the DependencyResolvers dictionary. Enabling the setter made me wonder if I should write through to the dictionary again, which seemed totally wrong. I then added the "dependency" member to the property wrapper, but that also seems unnecessary, since wrappedValue could be a computed property?
With my current knowledge, I would have expected that the flag mutation should be fine on the target instance, since the protocol specifies mutability via "set", and the instance itself is a refcounted class, not a value type.
A setter does make sense for mutating properties of value types, as far as I understand.
Does the compiler lose type information, and at which step? Is it a simplification in favor of value types? I hope someone can shed some light on this.
Thanks, and great forum!
public class DependencyResolver {
public static let shared = DependencyResolver()
private var dependencies: [String: Any] = [:]
public func register<T>(_ instance: T) {
let name = String(describing: T.self)
if dependencies.keys.contains(name) {
fatalError("registering instance für '\(name)' would overwrite previously registered instance. You can register each type only once.")
} else {
print("registering \(name)")
dependencies[name] = instance
}
}
public func resolve<T>() -> T {
let name = String(describing: T.self)
if dependencies.keys.contains(name) {
return dependencies[name] as! T
} else {
fatalError("couldn't find instance for type '\(name)'")
}
}
}
@propertyWrapper
public struct Inject<T> {
private var dependency: T
public init() {
dependency = DependencyResolver.shared.resolve()
}
public var wrappedValue: T {
get { dependency }
// set { dependency = newValue }
}
}
protocol Settings {
var flag: Bool { get set }
}
class SettingsDatasource: Settings {
var flag: Bool = true
}
let settingsDS = SettingsDatasource()
DependencyResolver.shared.register(settingsDS as Settings)
func test() {
@Inject var settings: Settings
settings.flag = false
}