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.36k stars 76 forks source link

Lazy initialization of ScopedServices #272

Closed uvaysss closed 1 year ago

uvaysss commented 1 year ago

Hey, I was wondering if there is a way to make the initialization of a ScopedService lazy when adding into the GlobalServices.

Zhuinden commented 1 year ago

Heyo, yes and no.

You do need to add something eagerly that will be able to receive the callbacks from simple-stack in case you need them.

However, that thing can lazily instantiate and store something.

The tricky thing there is to have a good name by which you reference it. When you use globalServices.add(t), you really are saying globalServices.addService(T::class.java, t).

So you could have something like this:

class CreateLazily<T>(private val factory: () -> T) {
    val instance by lazy { factory() }
}

and then

globalServices.addService("someName", CreateLazily { YourLazyObject() })

But now you have to know "someName" and to retrieve your instance as CreateLazily<YourLazyObject>.

(You could probably replace this idea of CreateLazily with Kotlin's Lazy directly https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-lazy/ ).

So nothing stops you from making something lazy (although when you'd be getting Bundleable or ScopedServices.Registered you would get initialized anyway 🤔 ) but giving a good name would be a struggle.

Personally I would add my object eagerly, and whatever you want as "a lazy service" should just be lazily initialized by that eagerly created service later.

Zhuinden commented 1 year ago

A scope node is meant to be immutable once created. I advise deferring laziness to an eagerly added scoped service that you add to service binder, and this scoped service will hold your Lazy<T>s + you must delegate the callbacks over if they are accessed.

This is outside the scope of Simple-Stack, as we have no prescriptions for the internals of a scoped service, and implementing Composite pattern + Lazy services would require such prescriptions.