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