Closed joeljfischer closed 5 months ago
Will peek, but doubt this will occur as I suspect it would require every step in the resolution chain (registration, caching, etc.) to also support async instances which would then mess with synchronous resolutions.
Might want to consider one of the two following approaches:
// something with an asynchronous initializer
struct AsyncInit {
let a: Int
init() async {
a = 1
}
}
// generic wrapper for any asynchronous initializer
struct AsyncInitWrapper<T> {
let wrapped: () async -> T
}
extension Container {
// Factory using initialization wrapper
var someAsyncObject: Factory<AsyncInitWrapper<AsyncInit>> {
self {
AsyncInitWrapper { await AsyncInit() }
}
}
// Factory using Task isolated context
var taskAsyncObject: Factory<Task<AsyncInit, Never>> {
self {
Task { await AsyncInit() }
}
}
}
func testAsyncInit() {
Task {
let a1 = await Container.shared.someAsyncObject().wrapped()
let a2 = await Container.shared.taskAsyncObject().value
}
}
Yeah, not going to work. Better to use one of the options shown earlier.
As mentioned, it would require every step in the resolution chain (registration, caching, etc.) to also support async instances which would then mess with synchronous resolutions. Or half the supporting infrastructure would have to be cloned to support async factories.
Too many easy options available for the rare case in which you're want to do it, as shown earlier.
I'm not sure how possible this would be, but it would vastly simplify some code that I'm moving into Actors for Swift 6 to allow it to use
init() async
and set up things like afor await
loop directly within the initializer and eliminate possible data races by usingTask
in the initializer.If it's not possible, then that's understandable, but it would be a great boon to using
actor
withFactory
in certain use cases where things have to be set-up at initialization time.