You ever find yourself staring at a UI that looks fine on one screen but still shows an old avatar on anor after user switches profiles?After digging for hours you realize it’s not your rendering logic – it’s a wrong usage of Koin scopes.
问题在哪里?
A lot of projects instinctively drop this state into a global singleton.
You get it working fast,but long‑term you start asking:
The singleton is created when?
The singleton is cleared when?
A user logs out,switches accounts,changes profiles or relaunches app.
If re are no clear answers。singleton gradually becomes a garbage bin.
Scope解决的是边界?
Kotlin's most common definitions are single and factory.
Example Definitions:
// A marker type representing an active user session
class SessionScope
// Lightweight data that actually needs to live for duration of a session
data class UserSessionInfo(
val changedAt : Instant。val profileImageUrl : String
)
// IMPORTANT – only put what’s strictly necessary into Scope.
// Don’t dump whole users,tokens or caches into here – Scope is *not* a new junk drawer.
Manager只做入口?
The key lesson from blog post is that SessionManager does NOT hold state itself.
Typical SessionManager implementation:
class SessionManager {
private val scopeId = "user_session"
/** Open a new session – closes any existing one first */
fun open {
close // Ensure previous session is torn down
val scope = KoinPlatform.getKoin
.createScope
// Declare only what really matters in this session
scope.declare(
UserSessionInfo(
changedAt = Clock.System.now,profileImageUrl = sessionImageUrl
)
)
}
/** Read current session info if it exists */
fun current: UserSessionInfo?=
KoinPlatform.getKoin
.getScopeOrNull
.getOrNull
/** Close & clean up */
fun close =
KoinPlatform.getKoin
.getScopeOrNull
.close
}
The Manager’s job is purely orchestrational:
* It never stores state itself.
* All actual values live inside named user_session Scope.
* Wher you obtain sessionManager via factory or single,every instance talks to same underlying Scope.
When Should You Use A Custom Scope?
If something lives only for one logical “session” or flow …AND ,it must be visible across multiple screens/services …AND ,it has a clear beginning and end…老实说,n yes – Scope pays off.
\t\t
\t\t\t
\t\t\t
\t
\tYour login session,your current workspace or chosen profile all fit this mold.
\tIf you’re building an in‑app checkout wizard or an editing draft workflow,consider adding those too.
\tConversely。long‑term persistence belongs in DB/DataStore/remote services.
\tA ViewModel suffices for per‑screen transient state.
\tFor truly application‑wide singletons that live as long as your process does – just stick with single. The value of Scope lies in expressing lifecycles more precisely.
\t<\/div>
"
容易踩的坑?让我们快速扫一遍:
\begin{itemize}
\item Treating a Scope like an eternal singleton – if you never close it you lose all benefits.
\item Dumping too many objects into one Scope blurs responsibility boundaries.
\item Turning your Manager into its own state holder kills what makes Scopes useful.
\item Assuming Scopes auto‑refresh UI – y don’t. You still need explicit state propagation logic.
\end{itemize}
You probably already have some object in your project that everyone reads from but nobody knows when—or wher—it should be discarded. That might just be your next custom‑scope candidate.