# Property wrappers + dependency injection: why do I need a setter here?

**URL:** <https://forums.swift.org/t/property-wrappers-dependency-injection-why-do-i-need-a-setter-here/57013>\
**Category:** Using Swift\
**Tags:** propertywrapper, dependency-injection\
**Created:** [April 27, 2022, 4:29pm UTC](https://forums.swift.org/t/property-wrappers-dependency-injection-why-do-i-need-a-setter-here/57013 "2022-04-27T16:29:05Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![lobotony](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lobotony/32/18965_2.png) [@lobotony](https://forums.swift.org/u/lobotony)\
**Post date:** [April 27, 2022, 4:29pm UTC](https://forums.swift.org/t/property-wrappers-dependency-injection-why-do-i-need-a-setter-here/57013/1 "2022-04-27T16:29:05Z")

</div>

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!

```swift

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

}

```

---

<div class="post-metadata">

**Author:** ![tem](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tem/32/21638_2.png) [@tem](https://forums.swift.org/u/tem)\
**Post date:** [April 27, 2022, 4:58pm UTC](https://forums.swift.org/t/property-wrappers-dependency-injection-why-do-i-need-a-setter-here/57013/2 "2022-04-27T16:58:11Z")

</div>

I think it's because you're storing an existential (aka protocol type), `Settings` (which needs to be spelled `any Settings` in Swift 6 FYI, and you can and should adopt this spelling today), and existentials are value types?

If you remove the `as Settings` and change the `settings` property to be `SettingsDatasource` then it seems to work. Perhaps you could use a super class instead of a protocol.

Or you could try to make it work with keypaths like SwiftUI's `@Environment`, or a similar solution that was recently shared here: [Dictionary with types as keys and different type values? - #13 by Jon\_Shier](https://forums.swift.org/t/dictionary-with-types-as-keys-and-different-type-values/56789/13)
