Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Weak Singleton. Provide dependencies based on arguments #451

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mikhailmaslo
Copy link

@mikhailmaslo mikhailmaslo commented Feb 4, 2023

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 & args in Component but not for AssemblyStorage. It seems that Component tests should be enough to cover AssemblyStorage usage

@CLAassistant
Copy link

CLAassistant commented Feb 4, 2023

CLA assistant check
All committers have signed the CLA.

@mikhailmaslo mikhailmaslo force-pushed the feature/extend-singleton-to-weak-singleton-and-args branch from 943b537 to 9965665 Compare February 4, 2023 14:40
@mikhailmaslo
Copy link
Author

@rudro
@neakor

Could you take a look and give your feedback, please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants