sourceafIoc::ScopeDef.fan


** Definition of a Scope. 
** 'ScopeDefs' are returned from [Registry.scopeDefs()]`Registry.scopeDefs`.
@Js
const mixin ScopeDef {
    
    ** The Scope's unique ID.
    abstract Str    id()
    
    ** Any aliases (IDs) given to the Scope.
    abstract Str[]  aliases()
    
    ** Returns 'true' if this scope is threaded.
    abstract Bool   threaded()
}

@Js
internal const class ScopeDefImpl : ScopeDef {
    override const Str      id
    override const Str[]    aliases
    override const Bool     threaded
             const Str[]    scopeIds
             const Unsafe   createRefs
             const Unsafe   destroyRefs

    new make(|This|in) {
        in(this)
    }
    
    Bool matchesId(Str scopeId) {
        id.equalsIgnoreCase(scopeId) || aliases.any { it.equalsIgnoreCase(scopeId) }
    }

    Err[]? callCreateHooks(Scope? parent) {
        errors  := null as Err[]
        configs := (Func[]?) createRefs.val
        if (configs != null && configs.isEmpty.not) {
            config  := ConfigurationImpl(parent, Str:|Scope|#, "afIoc::Scope.onCreate")
            configs.each {
                try {
                    it.call(config)
                    config.cleanupAfterMethod
                } catch (Err err) {
                    if (errors == null)
                        errors = Err[,]
                    errors.add(err)
                }
            }
            hooks := (Str:Func) config.toMap
            hooks.each {
                try it.call(parent)
                catch (Err err) {
                    if (errors == null)
                        errors = Err[,]
                    errors.add(err)
                }
            }
        }
        return errors
    }

    Err[]? callDestroyHooks(Scope? parent) {
        errors  := null as Err[]
        configs := (Func[]?) destroyRefs.val
        if (configs != null && configs.isEmpty.not) {
            config  := ConfigurationImpl(parent, Str:|Scope|#, "afIoc::Scope.onDestroy")
            configs.each {
                try {
                    it.call(config)
                    config.cleanupAfterMethod
                } catch (Err err) {
                    if (errors == null)
                        errors = Err[,]
                    errors.add(err)
                }
            }
            hooks := (Str:Func) config.toMap
            hooks.each {
                try it.call(parent)
                catch (Err err) {
                    if (errors == null)
                        errors = Err[,]
                    errors.add(err)
                }
            }
        }
        return errors
    }
}