func (a *servemodule) Configure(injector *dingo.Injector) {
	flamingo.BindEventSubscriber(injector).ToInstance(a)
	injector.BindMulti(new(cobra.Command)).ToProvider(func() *cobra.Command {
		return serveProvider(a, a.logger)
	})
}
Configure dependency injection
package flamingo
import (
	"context"
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"
	"time"
	"flamingo.me/dingo"
	"flamingo.me/flamingo/v3/core/runtime"
	"flamingo.me/flamingo/v3/core/zap"
	"flamingo.me/flamingo/v3/framework"
	"flamingo.me/flamingo/v3/framework/cmd"
	"flamingo.me/flamingo/v3/framework/config"
	"flamingo.me/flamingo/v3/framework/flamingo"
	"flamingo.me/flamingo/v3/framework/opencensus"
	"flamingo.me/flamingo/v3/framework/web"
	"github.com/spf13/cobra"
	"go.opencensus.io/plugin/ochttp"
)
type (
	Application struct {
		configDir       string
		childAreas      []*config.Area
		area            *config.Area
		args            []string
		routesModules   []web.RoutesModule
		defaultContext  string
		eagerSingletons bool
		flagset         *flag.FlagSet
	}
	ApplicationOption func(config *Application)
)
func ConfigDir(configdir string) ApplicationOption {
	return func(config *Application) {
		config.configDir = configdir
	}
}
func ChildAreas(areas ...*config.Area) ApplicationOption {
	return func(config *Application) {
		config.childAreas = areas
	}
}
func DefaultContext(name string) ApplicationOption {
	return func(config *Application) {
		config.defaultContext = name
	}
}
func SetEagerSingletons(enabled bool) ApplicationOption {
	return func(config *Application) {
		config.eagerSingletons = enabled
	}
}
func WithArgs(args ...string) ApplicationOption {
	return func(config *Application) {
		config.args = args
	}
}
func WithRoutes(routesModule web.RoutesModule) ApplicationOption {
	return func(config *Application) {
		config.routesModules = append(config.routesModules, routesModule)
	}
}
type eventRouterProvider func() flamingo.EventRouter
type arrayFlags []string
func (i *arrayFlags) String() string {
	return strings.Join(*i, ", ")
}
func (i *arrayFlags) Set(value string) error {
	*i = append(*i, value)
	return nil
}
func NewApplication(modules []dingo.Module, options ...ApplicationOption) (*Application, error) {
	app := &Application{
		configDir:      "config",
		args:           os.Args[1:],
		defaultContext: "root",
	}
	for _, option := range options {
		option(app)
	}
	app.flagset = flag.NewFlagSet("flamingo", flag.ContinueOnError)
	dingoTraceCircular := app.flagset.Bool("dingo-trace-circular", false, "enable dingo circular tracing")
	flamingoConfigLog := app.flagset.Bool("flamingo-config-log", false, "enable flamingo config logging")
	flamingoConfigCueDebug := app.flagset.String("flamingo-config-cue-debug", "", "query the flamingo cue config loader (use . for root)")
	flamingoContext := app.flagset.String("flamingo-context", app.defaultContext, "set flamingo execution context")
	var flamingoConfig arrayFlags
	app.flagset.Var(&flamingoConfig, "flamingo-config", "add additional flamingo yaml config")
	dingoInspect := app.flagset.Bool("dingo-inspect", false, "inspect dingo")
	if err := app.flagset.Parse(app.args); err != nil && err != flag.ErrHelp {
		return nil, fmt.Errorf("app: parsing arguments: %w", err)
	}
	if dingoTraceCircular != nil && *dingoTraceCircular {
		dingo.EnableCircularTracing()
	}
	modules = append([]dingo.Module{
		new(framework.InitModule),
		new(zap.Module),
		new(runtime.Module),
		new(cmd.Module),
	}, modules...)
	modules = append(modules, new(servemodule))
	for _, routesModule := range app.routesModules {
		modules = append(modules, dingo.ModuleFunc(func(injector *dingo.Injector) {
			web.BindRoutes(injector, routesModule)
		}))
	}
	root := config.NewArea("root", modules, app.childAreas...)
	configLoadOptions := []config.LoadOption{
		config.AdditionalConfig(flamingoConfig),
		config.DebugLog(*flamingoConfigLog),
		config.LegacyMapping(true, false),
	}
	if *flamingoConfigCueDebug != "" {
		printCue := func(b []byte, err error) {
			if err != nil {
				fmt.Println(err)
			}
			fmt.Println(string(b))
			os.Exit(-1)
		}
		if *flamingoConfigCueDebug == "." {
			configLoadOptions = append(configLoadOptions, config.CueDebug(nil, printCue))
		} else {
			configLoadOptions = append(configLoadOptions, config.CueDebug(strings.Split(*flamingoConfigCueDebug, "."), printCue))
		}
	}
	if err := config.Load(root, app.configDir, configLoadOptions...); err != nil {
		return nil, fmt.Errorf("app: config load: %w", err)
	}
	areas, err := root.Flat()
	if err != nil {
		return nil, fmt.Errorf("app: flat areas: %w", err)
	}
	var ok bool
	app.area, ok = areas[*flamingoContext]
	if !ok {
		return nil, fmt.Errorf("app: context %q not found", *flamingoContext)
	}
	injector, err := app.area.GetInitializedInjector()
	if err != nil {
		return nil, fmt.Errorf("app: get initialized injector: %w", err)
	}
	if *dingoInspect {
		inspect(injector)
	}
	if app.eagerSingletons {
		if err := injector.BuildEagerSingletons(false); err != nil {
			return nil, fmt.Errorf("app: build eager singletons: %w", err)
		}
	}
	return app, nil
}
func (app *Application) ConfigArea() *config.Area {
	return app.area
}
func App(modules []dingo.Module, options ...ApplicationOption) {
	app, err := NewApplication(modules, options...)
	if err != nil {
		log.Fatal(err)
	}
	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}
func (app *Application) Run() error {
	injector, err := app.area.GetInitializedInjector()
	if err != nil {
		return fmt.Errorf("get initialized injector: %w", err)
	}
	i, err := injector.GetAnnotatedInstance(new(cobra.Command), "flamingo")
	if err != nil {
		return fmt.Errorf("app: get flamingo cobra.Command: %w", err)
	}
	rootCmd := i.(*cobra.Command)
	rootCmd.SetArgs(app.flagset.Args())
	i, err = injector.GetInstance(new(eventRouterProvider))
	if err != nil {
		return fmt.Errorf("app: get eventRouterProvider: %w", err)
	}
	i.(eventRouterProvider)().Dispatch(context.Background(), new(flamingo.StartupEvent))
	return rootCmd.Execute()
}
func typeName(of reflect.Type) string {
	var name string
	for of.Kind() == reflect.Ptr {
		of = of.Elem()
	}
	if of.Kind() == reflect.Slice {
		name += "[]"
		of = of.Elem()
	}
	if of.Kind() == reflect.Ptr {
		name += "*"
		of = of.Elem()
	}
	if of.PkgPath() != "" {
		name += of.PkgPath() + "."
	}
	name += of.Name()
	return name
}
func trunc(s string) string {
	if len(s) > 25 {
		return s[:25] + "..."
	}
	return s
}
func printBinding(of reflect.Type, annotation string, to reflect.Type, provider, instance *reflect.Value, in dingo.Scope) {
	name := typeName(of)
	if annotation != "" {
		annotation = fmt.Sprintf("(%q)", annotation)
	}
	val := "<unset>"
	if instance != nil {
		val = trunc(fmt.Sprintf("%v", instance.Interface()))
	} else if provider != nil {
		val = "provider=" + provider.String()
	} else if to != nil {
		val = "type=" + typeName(to)
	}
	scopename := ""
	if in != nil {
		scopename = " (" + reflect.ValueOf(in).String() + ")"
	}
	fmt.Printf("%s%s: %s%s\n", name, annotation, val, scopename)
}
func inspect(injector *dingo.Injector) {
	fmt.Println("Bindings:")
	injector.Inspect(dingo.Inspector{
		InspectBinding: printBinding,
	})
	fmt.Println("\nMultiBindings:")
	injector.Inspect(dingo.Inspector{
		InspectMultiBinding: func(of reflect.Type, index int, annotation string, to reflect.Type, provider, instance *reflect.Value, in dingo.Scope) {
			printBinding(of, annotation, to, provider, instance, in)
		},
	})
	fmt.Println("\nMapBindings:")
	injector.Inspect(dingo.Inspector{
		InspectMapBinding: func(of reflect.Type, key string, annotation string, to reflect.Type, provider, instance *reflect.Value, in dingo.Scope) {
			printBinding(of, annotation, to, provider, instance, in)
		},
	})
	fmt.Println("---")
	injector.Inspect(dingo.Inspector{
		InspectParent: inspect,
	})
}
type servemodule struct {
	router            *web.Router
	server            *http.Server
	eventRouter       flamingo.EventRouter
	logger            flamingo.Logger
	configuredSampler *opencensus.ConfiguredURLPrefixSampler
	certFile, keyFile string
}
func (a *servemodule) Inject(
	router *web.Router,
	eventRouter flamingo.EventRouter,
	logger flamingo.Logger,
	configuredSampler *opencensus.ConfiguredURLPrefixSampler,
	cfg *struct {
		Port int `inject:"config:core.serve.port"`
	},
) {
	a.router = router
	a.eventRouter = eventRouter
	a.logger = logger
	a.server = &http.Server{
		Addr: fmt.Sprintf(":%d", cfg.Port),
	}
	a.configuredSampler = configuredSampler
}