hmlongco / Factory

A new approach to Container-Based Dependency Injection for Swift and SwiftUI.
MIT License
1.71k stars 107 forks source link

Question about scopes in different containers #86

Closed IvanShah closed 1 year ago

IvanShah commented 1 year ago

Hello I have a problem with scopes of some services which I want share between containers as singletons. The service created as many times as it injects by different containers. In the next example sharedService inits twice when MyConstructedService is created and when sharedService injected by something else. What I need: only one sharedService ever. How I can do that?

extension SharedContainer {
    var sharedService: Factory<MyServiceType> { self { MyService() }.singleton }
}

final class DemoContainer: ObservableObject, SharedContainer {
    static var shared = DemoContainer()

    var constructedService: Factory<MyConstructedService> {
        self {
            MyConstructedService(service: sharedService())
        }
    }

    var manager = ContainerManager()
}

Thank you

hmlongco commented 1 year ago

I think singletons may need some rework as the way they're implemented in 2.0 gives rise to the issues you've illustrated.

Given the current architecture, you may do do something like...

final class SingletonContainer: SharedContainer {
    static var shared = SingletonContainer()
    var singletonService: Factory<MyServiceType> {
        self { MyService() }.singleton
    }
    var manager = ContainerManager()
}

extension SharedContainer {
    var sharedService: Factory<MyServiceType> {
        self { SingletonContainer.shared.singletonService() }
    }
}

final class DemoContainer: SharedContainer {
    static var shared = DemoContainer()
    var constructedService: Factory<MyConstructedService> {
        self { MyConstructedService(service: self.sharedService()) }
    }
    var manager = ContainerManager()
}

It's clunky, but the best I can think of until 2.1 is released.

IvanShah commented 1 year ago

Thank you for workaround. Looking forward to update