package common type Config interface { Name() string Starter() StartFct Children() []Config Add(Config) } type Context interface { Config() Config Parent() Context Services() map[string]Context ChildContext(Config) Context } type StartFct = func(Context) // Context implementation type context struct { cfg Config parent Context } func (ctx *context) Config() Config { return ctx.cfg } func (ctx *context) Parent() Context { return ctx.parent } func (ctx *context) Services() map[string]Context { return ctx.parent.Services() } func (ctx *context) ChildContext(cfg Config) Context { cctx := context{cfg, ctx} ctx.Services()[cfg.Name()] = &cctx return &cctx } // top-level application context type appContext struct { *context services map[string]Context } func (ctx *appContext) ChildContext(cfg Config) Context { cctx := context{cfg, ctx} ctx.services[cfg.Name()] = &cctx return &cctx } func (ctx *appContext) Services() map[string]Context { return ctx.services } func AppContext(cfg Config) Context { return &appContext{ context: &context{cfg, nil}, services: map[string]Context{}, } }