Introduce Weak Singleton. Provide dependencies based on arguments
Introduction of Weak Singleton
Needle has been providing users with singleton dependencies through its shared method, which is the most common use case for dependency injection. However, there are situations where weak singletons can be more appropriate.
For instance, when multiple objects require the same new dependency, using a weak singleton instead of a traditional singleton can be more efficient. In such a case dependency provided as a weak singleton can be safely destroyed when no one needs it and recreated again when it's used, as opposed to singleton which remains in memory and potentially retaining previous state.
Introduction of arguments
There are cases, when it's convenient to create unique object per some unique feature. For example, you might need a separate object per object id or you might want to make unique data fetcher per endpoint, etc
With this change, it would be possible to create an object based on arguments. Arguments is an instance which should be Hashable for comparison. Providing different arguments for singleton will result in a new singleton per unique argument. The same logic applies to weak singletons.
Example:
// ProductComponent
func productModel(productID: String) -> ProductModel {
return shared(args: productID) { ... }
}
let productModel1 = productComponent.productModel(productID: productID1) // is unique instance
let productModel2 = productComponent.productModel(productID: productID2) // is unique instance
let productModel3 = productComponent.productModel(productID: productID1) // is the same instance as productModel1 because arguments is the same - productID1
Replace String with StaticString in #function
In the current needle implementation __function parameter used as a key for dependency which is great because it's unique in the scope of the component and it's efficient.
Since arguments is introduced and __function is not the only key to dependency anymore, we can consider using StaticString instead. #function expression is replaced with the actual value at a compile time, so they are basically StaticString. As an adventage, StaticString can be compared by reference which is faster than string comparison
It's not a required change but seems to be appropriate in the context of arguments introduction
Side notes
- I'm not sure which copyright should be used in new files, so I've just left the default ones. Let me know, if it needs to be changed.
- I've added tests for
weakSingleton&argsinComponentbut not forAssemblyStorage. It seems thatComponenttests should be enough to coverAssemblyStorageusage
@rudro @neakor
Could you take a look and give your feedback, please?