예제 #1
0
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}
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
// 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
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
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!
}
예제 #8
0
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
}
예제 #9
0
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)
}
예제 #10
0
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("!!!")
	}
}
예제 #11
0
	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
}
예제 #12
0
	. "github.com/onsi/gomega"

	"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)
예제 #13
0
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")