Hello community!
I’ve been working on a simple package that tries to abstract Dependency Injection frameworks with a common API. I’m building it with approachable concurrency in mind, opting-in default isolation to MainActor, NonisolatedNonsendingByDefault and InferIsolatedConformances.
I defined these top level domain types:
/// A closure that produces new instances of a service type.
public typealias Factory<P> = () -> P
/// A type that describes a registration entry in a ``Container``
public typealias Registration<P> = (type: P.Type, factory: Factory<P>)
Everything works fine when I use them with Swinject:
public final class SwinjectContainer: Didi.Container {
private let container: Swinject.Container
/// ...
public func register<P>(_ component: () -> Registration<P>) {
let (service, factory) = component()
container.register(service, factory: { _ in factory() }) // <- Using my `Factory` typealias
}
/// ...
}
but I’m having issues when using them with Factory:
public final class FactoryContainer: Didi.Container {
private let container: any FactoryKit.Resolving
/// ...
public func register<P>(_ component: () -> Registration<P>) {
let registration = component()
_ = container.register(
registration.type,
factory: { registration.factory() } // <- Capture of 'registration' with non-Sendable type 'Registration<P>' (aka '(type: P.Type, factory: () -> P)') in a '@Sendable' closure
)
}
/// ...
}
That’s because Factory’s register function declares the factory closure as @Sendable:
public protocol Resolving: ManagedContainer {
func register<T>(_ type: T.Type, factory: @escaping @Sendable () -> T) -> Factory<T>
/// ...
}
I’m able to get rid of the error defining my Factory closure as follows:
/// A closure that produces new instances of a service type.
public typealias Factory<P> = @Sendable () -> P // <- Added `@Sendable`
From a modeling point of view, what should be the right thing to do?
Am I changing my package just beacuse a third-party framework uses a @Sendable closure? What are the trade-offs of making my Factory typealias as non-Sendable?
Any clarification/thought is appreciated!