hmlongco / Factory

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

Singleton scope instances are created multiple times #99

Closed deivitaka closed 1 year ago

deivitaka commented 1 year ago

On a multiple module setup, if a class has the same name across modules, even if it has singleton scope, it gets created multiple times. This is only present in v2.1.3, on 2.1.2 it works normally.

I have attached a very basic project to replicate this issue. FactoryBug.zip

hmlongco commented 1 year ago

So yes. You're creating the same class with the same name in multiple modules with a singleton scope. Singletons use a mashup of the factory function name and the type name as cache key. So basically you're using the same identical function name AND the same identical class name--even though they're actually different types--in different modules. So the name is found is found in the singleton cache but the actual type is different so it's recreated and recached.

I'll look to see what I can do, but as discussed in the documentation singletons are somewhat problematic to use in your code. Given your example of simply using the shared container instance, you'd be better off simply specifying the scope as .cached.

See the section on singletons in the Testing documentation.

deivitaka commented 1 year ago

Thanks for the info. I failed to notice the function name also affects the cache key, which would also be acceptable to change.

Given my scenario, I have a wrapper for UserDefaults with the same name / functionality, but still would be unique singletons with different properties. So would be nice to consider the module name also in the cache key. Also in cases of third party packages that use Factory (in the rare occasion they may collide).

I would close this, since there is a workaround / preferred usage.

hmlongco commented 1 year ago

You can (at the moment), also sneak in and change the internal key yourself.

    public var sharedClass: Factory<SharedClass> {
        self(key: "sharedClassB") { .init() }.singleton
    }
hmlongco commented 1 year ago

Will be fixed in 2.1.4

hmlongco commented 1 year ago

Fixed.