Skip to content

Instantly share code, notes, and snippets.

@jdavisclark
Last active February 11, 2023 06:02
Show Gist options
  • Select an option

  • Save jdavisclark/c779765dc68a054869606ece0a5ab825 to your computer and use it in GitHub Desktop.

Select an option

Save jdavisclark/c779765dc68a054869606ece0a5ab825 to your computer and use it in GitHub Desktop.
IOC with a localised container
package main
import (
"errors"
"fmt"
"os"
"reflect"
)
type Writer interface {
Write(string)
}
type ConsoleWriter struct{}
func (w ConsoleWriter) Write(s string) {
fmt.Println(s)
}
func main() {
container := IOCContainer{container: map[string]interface{}{}}
err := Register[Writer, ConsoleWriter](container, ConsoleWriter{})
if err != nil {
fmt.Printf("error registering: %e\n", err)
os.Exit(1)
}
w, ok := Resolve[Writer](container)
if !ok {
fmt.Println("error resolving: didnt find type")
os.Exit(1)
}
w.Write("nice")
}
type IOCContainer struct {
container map[string]interface{}
}
func Register[tIface any, tImpl any](container IOCContainer, impl tImpl) error {
thing := reflect.TypeOf((*tIface)(nil)).Elem()
name := thing.Name()
return container.Register(name, impl)
}
func Resolve[typeIface any](container IOCContainer) (typeIface, bool) {
thing := reflect.TypeOf((*typeIface)(nil)).Elem()
name := thing.Name()
genericImpl, err := container.Get(name)
if err != nil {
return
}
return genericImpl.(typeIface), true
}
func (c *IOCContainer) Register(name string, impl interface{}) error {
c.container[name] = impl
return nil
}
func (c *IOCContainer) Get(name string) (interface{}, error) {
v, ok := c.container[name]
if !ok {
return nil, errors.New("got nothing")
}
return v, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment