-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Support @MainActor-isolated initializers in factory/singleton registrations
Problem
WhoopDIKit's factory closures are stored and called with no actor context, so Swift 6 strict concurrency rejects registering any type with a @MainActor-isolated init.
This comes up with patterns like:
@MainActor
public protocol AsyncViewModel { ... }
@MainActor
final class MyViewModel: AsyncViewModel {
init(service: MyService) { ... } // implicitly @MainActor
}Registering this fails to compile:
final class MyModule: DependencyModule {
override func defineDependencies() {
factory {
// ❌ Main actor-isolated initializer cannot be referenced from a non-isolated context
MyViewModel(service: try self.get())
}
}
}Workarounds
nonisolated init — Swift 6
If the init only sets stored properties, nonisolated is safe. @MainActor isolation applies to methods on self after init, not to setting stored properties.
@MainActor
final class MyViewModel: AsyncViewModel {
nonisolated init(service: MyService) {
self.service = service
}
}Inject a factory closure — Swift 6
Register a @MainActor () -> MyViewModel instead of the type directly.
WhoopDI resolves dependencies; you construct on the main actor at the call
site.
// Module
factory {
let service: MyService = try self.get()
return { @MainActor in MyViewModel(service: service) } as (@MainActor ()
-> MyViewModel)
}
// @MainActor call site
let makeVM: @MainActor () -> MyViewModel = WhoopDI.inject()
let vm = makeVM()Swift 5 language mode
Without strict concurrency enabled, this compiles and works fine at runtime as long as inject is always called from the main thread
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels