4. Bootstrap
• Define the configuration Areas
• Load default configuration
• Load the current configuration and routing information
• Load overriding configuration
• Register additional Handlers
• Run the main command / Start a router
11. General
• Bind dependencies on application startup (in code)
• (future support for compile-type bindings)
• Config-Tree based injector-trees: It's possible to inject
different services/adapters for certain configuration areas
13. Annotation
• Default annotation is empty
injector.Bind(new(Iface)).AnnotatedWith("special-case").To(IfaceImpl{})
• Inject via
func (instance *MyType) Inject(annotated *struct{
IfaceInstance Iface `inject:"special-case"`
}) {
instance.iface = annotated.IfaceInstance
}
• Used by configuration for configuration values
14. Singleton Scopes
• If really necessary it is possible to use singletons
• .AsEagerSingleton() binds as a singleton, and loads it
when the application is initialized
• .In(dingo.Singleton) makes it a global singleton
• .In(dingo.ChildSingleton) makes it a singleton limited to
the config area
15. MultiBindings
• Allows to bind multiple instances/providers/types for one
type
func (*Module) Configure(injector *dingo.Injector) {
injector.BindMulti(new(Iface)).To(IfaceImpl1{})
injector.BindMulti(new(Iface)).To(IfaceImpl2{})
}
func (*MyService) Inject(ifaces []Iface) {}
16. MapBindings
• Similiar to Multibindings, but with a key instead of a list
func (*Module) Configure(injector *dingo.Injector) {
injector.BindMap(new(Iface), "key1").To(IfaceImpl1{})
injector.BindMap(new(Iface), "key2").To(IfaceImpl2{})
}
func (*MyService) Inject(ifaces map[string]Iface) {}
17. Provider
• If you need to make sure bindings are lazy evaluated, or
need multiple instances of a certain type, it is possible to
inject provider
• Define a type which ends with Provider, and gives you
what you need:
type IfaceProvider func() Iface
func (*Service) Inject(provider IfaceProvider) {
ifaceInstance := provider()
}
18. Provider
• It is possible to get provider for map/multibindings
• It is possible to get provider for provider
• Use with care: this might be an indicator of too complicated
code
20. config.Map
• config.Map is a container for string -> interface{}
• configuration is available via annotated injection
• MyConfig string inject:"config:my.config"
• My config.Map `inject:"config:my"`
• Numbers: int is also float64
21. Config Merging
• Dot . separated config keys
• Every . donates one level in the tree:
my.config.value: hello
my:
config:
value: hello
22. Config Merging
• Config Maps are deep merged
• Allows overriding sub-keys:
my:
foo: bar
config:
value: hello
value2: world
my.config.value: myhello
25. Configuration Areas
• Flamingo Config is hierarchical
• Config Areas can have multiple children, they inherit
config and dependency injection bindings
• Config is loaded based on file-system layout
27. Default Configuration
• Modules in Flamingo can provide a default config, and
override existing config during the bootstrap
• The default configuration is loaded before the config
folder
• The override configuration can manipulate configuration
afterwards (use with care!)
31. Routing: Paths
• Named Parameters: /route/:name
• Match everything until the following /
• Regex Parameters: /route/$name<[a-z]{2,}>
• Match everything which is captured by the regex (if
possible)
• Wildcard Parameters: /route/*name
• Match everything (everything until the end of the route)
32. Routing: Controller
• Map a route to a controller, either in routes.yml or in code
• my.controller
• Gets all URL parameters
• my.controller(name="foo")
• Sets name to foo
• my.controller(name?="foo")
• Sets name to foo if not set by a GET parameter
• my.controller(name?)
• Sets name to the value of the name GET parameter, if available
33. Routing: Reverse
• Reverse URLs are build based on available routes
• web.ReverseRouter
• Newest routes take precendence
• Router parameters are taken into account, meaning:
• /home -> cms.view(page="home")
• url("cms.view", router.P{"page": "home"}) -> /home
34. web.RouterRegistry
• HandleGet(context.Context, *web.Request) web.Result for
GET
• HandlePost(context.Context, *web.Request) web.Result for
POST
• Same for HEAD, DELETE, PUT
• HandleAny
• HandleData(context.Context, *web.Request) interface{} for
internal data requests
36. core.Prefixrouter
• The core.Prefixrouter module provides a HTTP Router
which routes requests based on hostname/path
• When starting Flamingo the module will create HTTP
listener for all config Areas with a prefixrouter.baseurl
configuration
38. core.Cmd
• Based on spf13/cobra
• Inject *cobra.Command with annotation flamingo to get
the main command
• Bind to cobra.Command to add custom commands