Skip to content

Add non-mutating support to LazyInjected for use in value types (struct) #339

@o-nnerb

Description

@o-nnerb

Description:

Currently, LazyInjected<T> can't be used inside a struct unless the entire struct is marked as mutating whenever the wrapped value is accessed. This severely limits its usability in value-type contexts, especially in SwiftUI views or other immutable setups where mutation isn't desired or even possible (e.g., inside let constants or non-mutating closures).

The issue stems from the wrappedValue implementation, which is declared as mutating get. While lazy initialization inherently implies mutation of internal state, it’s possible to work around this in Swift by using reference types internally (e.g., a private class holder) to manage the lazy resolution without requiring the outer wrapper to be mutating.

Proposed solution

Refactor LazyInjected to store its state (like dependency and initialize) in a separate reference-type container (e.g., LazyStorage<T>). This would allow wrappedValue to be non-mutating from the consumer’s perspective while still enabling lazy resolution under the hood.

This pattern is already used by other property wrappers in the Swift ecosystem (e.g., @StateObject in SwiftUI) and would preserve the current API while greatly expanding compatibility.

Current limitation example

struct MyView {
    @LazyInjected(\.myService) private var service // ❌ Can't use without mutating context
}

This forces awkward workarounds or prevents adoption in pure value-type architectures.

Benefits

  • Enables use of LazyInjected in structs without requiring mutating methods.
  • Maintains lazy, on-demand resolution semantics.
  • Keeps backward compatibility if implemented carefully.

Would you be open to a PR implementing this approach?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions