Zhuinden / simple-stack

[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).
Apache License 2.0
1.37k stars 75 forks source link

Question: What is the purpose of RegistrationViewModel inside ServiceProvider in extension-compose-example? #266

Closed ydhnwb closed 1 year ago

ydhnwb commented 1 year ago

I've read the documentation, your video about simple-stack on youtube and the example code at extension-examples-compose like below:

image

I don't know the purpose of adding "RegistrationViewModel" into it? Is it because the RegistrationViewModel is used by tow fragment (CreateLoginCredentials and EnterProfileData) like below?

image

Is it the instance will cleared when the fragments who consume it with ScopeKey.Child get closed by backstack?

image

image

Zhuinden commented 1 year ago

Good questions!

Theoretically I could have registered RegisterViewModel via ScopeKey from the first screen (i think it's EnterProfileDataKey), and you'd be able to see it on the second screen's Fragment via by lazy { lookup<RegistrationViewModel>() } as well. This is what the video calls implicit parents.

But in this sample I specifically used ScopeKey.Child (explicit parents) because it portrays how you can define a shared scope that is instantiated if any of the keys are added, and not just specifically the first step (oftentimes you have a ui flow to implement with multiple steps, and some are optional -- imagine getting a crash because the first step is no longer needed, only 2-3-4th 🤦)

It's also useful for backstack.exitScope() and backstack.exitScopeTo().

Is it because the RegistrationViewModel is used by tow fragment (CreateLoginCredentials and EnterProfileData) like below?

Yes, if you can't guarantee that a given key exists but "one of multiple keys" does, then if "one of the keys" is in the history, then the scope is kept alive.

Is it the instance will cleared when the fragments who consume it with ScopeKey.Child get closed by backstack?

If there is no key that defines the scope as a parent, then it will be destroyed (and for any scoped-service such as RegistrationViewModel is added to this scope, then onServiceUnregistered() will be invoked on it, if it implements ScopedServices.Registered).


One thing, ServiceProvider extends from DefaultServiceProvider() because the keys defining the required services is a reasonable default, however it is also customizable (this can come up in multi-module environments, I had to use multibinding for this once ~ which is also something I mention in the talk, although I wonder if it wasn't really that clear as to "why").

ydhnwb commented 1 year ago

Ah I see, it's as simple as two fragments that implement ScopeKey.Child will try to lookup (potentially) same service by looking at it's TAG.

So, with this teory, I can pull service that I shared as many as I need it?🤔

Zhuinden commented 1 year ago

Technically it's the key that implements ScopeKey.Child not the fragment, but yes, you can pull the service that you shared as many as you want.

The service provider class in the sample is to show that if you define a custom scope, then you'll need to pass a more customized class than just DefaultServiceProvider.

ydhnwb commented 1 year ago

It clears my head. Thanks