func ExampleNewType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) // register the type using the factory function NewMockTypeWithArgs and pass two arguments container.Register("my_type", goldi.NewType(NewMockTypeWithArgs, "Hello World", true)) t := container.MustGet("my_type").(*MockType) fmt.Printf("%#v", t) // Output: // &goldi_test.MockType{StringParameter:"Hello World", BoolParameter:true} }
func ExampleNewFuncReferenceType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) logger := new(SimpleLogger) container.Register("logger", goldi.NewInstanceType(logger)) container.Register("log_func", goldi.NewFuncReferenceType("logger", "DoStuff")) f := container.MustGet("log_func").(func(string) string) fmt.Println(f("Hello World")) // executes logger.DoStuff // Output: // Hello World }
func ExampleContainer() { registry := goldi.NewTypeRegistry() config := map[string]interface{}{} container := goldi.NewContainer(registry, config) container.Register("logger", goldi.NewType(NewNullLogger)) l := container.MustGet("logger") fmt.Printf("%T", l) // Output: // *goldi_test.NullLogger }
// Let's assume that we have a LoggerProvider type that produces configured instances // of a Logger each time we call LoggerProvider.GetLogger(loggerName string). // // The example shows how to register a `logger` as proxy for a specific call to this LoggerProvider. func ExampleNewProxyType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) // register some type as always container.Register("logger_provider", goldi.NewStructType(LoggerProvider{})) // register a proxy type that references the method of previously defined type and append call arguments if any container.Register("logger", goldi.NewProxyType("logger_provider", "GetLogger", "My logger")) l := container.MustGet("logger").(*SimpleLogger) fmt.Printf("%s: %T", l.Name, l) // Output: // My logger: *goldi_test.SimpleLogger }
func ExampleNewAliasType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) container.Register("logger", goldi.NewStructType(SimpleLogger{})) container.Register("default_logger", goldi.NewAliasType("logger")) container.Register("logging_func", goldi.NewAliasType("logger::DoStuff")) fmt.Printf("logger: %T\n", container.MustGet("logger")) fmt.Printf("default_logger: %T\n", container.MustGet("default_logger")) fmt.Printf("logging_func: %T\n", container.MustGet("logging_func")) // Output: // logger: *goldi_test.SimpleLogger // default_logger: *goldi_test.SimpleLogger // logging_func: func(string) string }
func ExampleNewStructType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) // all of the following types are semantically identical container.Register("foo_1", goldi.NewStructType(Foo{})) container.Register("foo_2", goldi.NewStructType(&Foo{})) container.Register("foo_3", goldi.NewStructType(new(Foo))) // each reference to the "logger" type will now be resolved to that instance fmt.Printf("foo_1: %T\n", container.MustGet("foo_1")) fmt.Printf("foo_2: %T\n", container.MustGet("foo_2")) fmt.Printf("foo_3: %T\n", container.MustGet("foo_3")) // Output: // foo_1: *goldi_test.Foo // foo_2: *goldi_test.Foo // foo_3: *goldi_test.Foo }
func ExampleNewConfiguredType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) // this example configurator accepts a Foo type and will set its Value field to the given value configurator := &MyConfigurator{ConfiguredValue: "success!"} // register the configurator under a type ID container.Register("configurator_type", goldi.NewInstanceType(configurator)) // create the type that should be configured embeddedType := goldi.NewStructType(Foo{}) container.Register("foo", goldi.NewConfiguredType(embeddedType, "configurator_type", "Configure")) fmt.Println(container.MustGet("foo").(*Foo).Value) // Output: // success! }
func ExampleContainer_Get() { registry := goldi.NewTypeRegistry() config := map[string]interface{}{} container := goldi.NewContainer(registry, config) container.Register("logger", goldi.NewType(NewNullLogger)) l, err := container.Get("logger") if err != nil { fmt.Println(err.Error()) return } // do stuff with the logger. usually you need a type assertion fmt.Printf("%T", l.(*NullLogger)) // Output: // *goldi_test.NullLogger }
func Example() { // create a new container when your application loads registry := goldi.NewTypeRegistry() config := map[string]interface{}{ "some_parameter": "Hello World", "timeout": 42.7, } container := goldi.NewContainer(registry, config) // now define the types you want to build using the di container // you can use simple structs container.RegisterType("logger", &SimpleLogger{}) container.RegisterType("api.geo.client", new(GeoClient), "http://example.com/geo:1234") // you can also use factory functions and parameters container.RegisterType("acme_corp.mailer", NewAwesomeMailer, "first argument", "%some_parameter%") // dynamic or static parameters and references to other services can be used as arguments container.RegisterType("renderer", NewRenderer, "@logger") // closures and functions are also possible container.Register("http_handler", goldi.NewFuncType(func(w http.ResponseWriter, r *http.Request) { // do amazing stuff })) // once you are done registering all your types you should probably validate the container validator := validation.NewContainerValidator() validator.MustValidate(container) // will panic, use validator.Validate to get the error // whoever has access to the container can request these types now logger := container.MustGet("logger").(LoggerInterface) logger.DoStuff("...") // in the tests you might want to exchange the registered types with mocks or other implementations container.RegisterType("logger", NewNullLogger) // if you already have an instance you want to be used you can inject it directly myLogger := NewNullLogger() container.InjectInstance("logger", myLogger) }
func ExampleNewFuncType() { container := goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) // define the type container.Register("my_func", goldi.NewFuncType(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "test" { w.WriteHeader(http.StatusAccepted) } })) // generate it result, err := container.Get("my_func") if err != nil { return } // call it f := result.(func(name string, age int) (bool, error)) ok, err := f("foo", 42) if ok != true || err != nil { panic("!!!") } }
Describe("Arguments()", func() { It("should return an empty list", func() { typeDef := goldi.NewFuncType(SomeFunctionForFuncTypeTest) Expect(typeDef.Arguments()).NotTo(BeNil()) Expect(typeDef.Arguments()).To(BeEmpty()) }) }) Describe("Generate()", func() { var ( config = map[string]interface{}{} container *goldi.Container resolver *goldi.ParameterResolver ) BeforeEach(func() { container = goldi.NewContainer(goldi.NewTypeRegistry(), config) resolver = goldi.NewParameterResolver(container) }) It("should just return the function", func() { typeDef := goldi.NewFuncType(SomeFunctionForFuncTypeTest) Expect(typeDef.Generate(resolver)).To(BeAssignableToTypeOf(SomeFunctionForFuncTypeTest)) }) }) }) func SomeFunctionForFuncTypeTest(name string, age int) (bool, error) { return true, nil }
"github.com/fgrosse/goldi" "github.com/fgrosse/goldi/validation" ) var _ = Describe("ContainerValidator", func() { var ( registry goldi.TypeRegistry config map[string]interface{} container *goldi.Container validator *validation.ContainerValidator ) BeforeEach(func() { registry = goldi.NewTypeRegistry() config = map[string]interface{}{} container = goldi.NewContainer(registry, config) validator = validation.NewContainerValidator() }) It("should return an error if an invalid type was registered", func() { registry.Register("main_type", goldi.NewFuncReferenceType("not_existent", "type")) Expect(validator.Validate(container)).NotTo(Succeed()) }) It("should return an error when parameter has not been set", func() { typeDef := goldi.NewType(NewMockTypeWithArgs, "hello world", "%param%") registry.Register("main_type", typeDef) Expect(validator.Validate(container)).NotTo(Succeed()) })
package goldi_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "fmt" "github.com/fgrosse/goldi" ) var _ = Describe("TypeConfigurator", func() { var container *goldi.Container BeforeEach(func() { container = goldi.NewContainer(goldi.NewTypeRegistry(), map[string]interface{}{}) }) Describe("Configure", func() { Context("when the type configurator has not been defined correctly", func() { It("should return an error", func() { someType := new(Foo) configurator := goldi.NewTypeConfigurator("configurator", "Configure") Expect(configurator.Configure(someType, container)).To(MatchError(`the configurator type "@configurator" has not been defined`)) }) }) Context("when the type configurator is no struct or pointer to struct", func() { It("should return an error", func() { container.InjectInstance("configurator", 42) someType := new(Foo) configurator := goldi.NewTypeConfigurator("configurator", "Configure")
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "fmt" "github.com/fgrosse/goldi" ) var _ = Describe("TypeRegistry", func() { var ( registry goldi.TypeRegistry resolver *goldi.ParameterResolver ) BeforeEach(func() { registry = goldi.NewTypeRegistry() container := goldi.NewContainer(registry, map[string]interface{}{}) resolver = goldi.NewParameterResolver(container) }) Describe("RegisterType", func() { Context("with factory function type", func() { It("should store the type", func() { typeID := "test_type" factory := &MockTypeFactory{} registry.RegisterType(typeID, factory.NewMockType) factoryWrapper, typeIsRegistered := registry[typeID] Expect(typeIsRegistered).To(BeTrue()) Expect(factoryWrapper).NotTo(BeNil()) factoryWrapper.Generate(resolver)