- Pods
- AF-IOC 1.2.2
- API
- LocalStash
- Src
sourceafIoc::LocalStash.fan
using concurrent
** A wrapper around [Actor.locals]`concurrent::Actor.locals` ensuring a unique namespace per
** instance. this means you don't have to worry about name clashes.
**
** Example usage:
**
** pre>
** stash1 := LocalStash()
** stash1["wot"] = "ever"
**
** stash2 := LocalStash()
** stash2["wot"] = "banana"
**
** Obj.echo(stash1["wot"]) // --> ever
** <pre
**
** Though typically you would create calculated field wrappers:
**
** pre>
** const class Example
** private const LocalStash stash := LocalStash(typeof)
**
** MyService wotever {
** get { stash["wotever"] }
** set { stash["wotever"] = it }
** }
** }
** <pre
**
const class LocalStash {
private const Str prefix
private Int? counter {
get { Actor.locals["${typeof.qname}.counter"] }
set { Actor.locals["${typeof.qname}.counter"] = it }
}
new make() {
this.prefix = createPrefix(typeof)
}
** Adds the type name to the 'locals' key - handy for debugging.
** See `IocHelper.locals`
new makeFromType(Type type) {
this.prefix = createPrefix(type)
}
@Operator
Obj? get(Str name, |->Obj|? defFunc := null) {
val := Actor.locals[key(name)]
if (val == null) {
if (defFunc != null) {
val = defFunc.call
set(name, val)
}
}
return val
}
@Operator
Void set(Str name, Obj? value) {
Actor.locals[key(name)] = value
}
** Returns all keys associated / used with this stash
Str[] keys() {
Actor.locals.keys
.findAll { it.startsWith(prefix) }
.map |key->Str| { stripPrefix(key) }
}
override Str toStr() {
"LocalStash with prefix - $prefix"
}
private Str createPrefix(Type type) {
count := counter ?: 1
padded := count.toStr.padl(4, '0')
prefix := "${type.name}.${padded}."
counter = count + 1
return prefix
}
private Str key(Str name) {
return "${prefix}${name}"
}
private Str stripPrefix(Str name) {
if (name.startsWith(prefix))
return name[prefix.size..-1]
else
return name
}
}