container

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2023 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewContainer

func NewContainer() *container
Example (CircularDependency)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Spouse struct {
	Name   string
	Spouse *Spouse
}

func main() {
	wife := container.NewService()
	wife.SetConstructor(func() *Spouse {
		return &Spouse{}
	})
	wife.SetField("Name", container.NewDependencyValue("Mary Jane"))
	wife.SetField("Spouse", container.NewDependencyService("husband"))

	husband := container.NewService()
	husband.SetConstructor(func() *Spouse {
		return &Spouse{}
	})
	husband.SetField("Name", container.NewDependencyValue("Peter Parker"))
	husband.SetField("Spouse", container.NewDependencyService("wife"))

	c := container.NewContainer()
	c.OverrideService("wife", wife)
	c.OverrideService("husband", husband)

	_, err := c.Get("wife")
	fmt.Println(err)

}
Output:

container.get("wife"): circular dependencies: @husband -> @wife -> @husband
Example (CopyServiceToError)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

type People struct {
	People []Person
}

func main() {
	p := container.NewService()
	p.SetValue(Person{})
	p.SetField("Name", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	c.OverrideService("mary", p)

	var mary People
	err := c.CopyServiceTo("mary", &mary)
	fmt.Println(err)

}
Output:

container.CopyServiceTo("mary"): reflect.Set: value of type container_test.Person is not assignable to type container_test.People
Example (CopyServiceToOK)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	p := container.NewService()
	p.SetValue(Person{})
	p.SetField("Name", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	c.OverrideService("mary", p)

	var mary Person
	_ = c.CopyServiceTo("mary", &mary)
	fmt.Println(mary)

}
Output:

{Mary Jane}
Example (Decorator)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Greeter interface {
	Greet() string
}

type greeter struct{}

func (g greeter) Greet() string {
	return "How are you?"
}

type politeGreeter struct {
	parent Greeter
}

func (p politeGreeter) Greet() string {
	return fmt.Sprintf("Hello! %s", p.parent.Greet())
}

func PoliteGreeterDecorator(ctx container.DecoratorContext) politeGreeter {
	return politeGreeter{
		parent: ctx.Service.(greeter),
	}
}

func main() {
	g := container.NewService()
	g.SetValue(greeter{})
	g.Tag("greeter-tag", 0)

	c := container.NewContainer()
	c.OverrideService("greeter", g)
	c.AddDecorator("greeter-tag", PoliteGreeterDecorator)

	var greeterObj Greeter
	_ = c.CopyServiceTo("greeter", &greeterObj)
	fmt.Println(greeterObj.Greet())

}
Output:

Hello! How are you?
Example (ErrorFieldDoesNotExist)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	mary := container.NewService()
	mary.SetConstructor(func() Person {
		return Person{}
	})
	// it's an invalid field name, it cannot work!
	mary.SetField("FullName", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	c.OverrideService("mary", mary)

	_, err := c.Get("mary")
	fmt.Println(err)

}
Output:

container.get("mary"): set field "FullName": set `*interface {}`."FullName": field `FullName` does not exist
Example (ErrorServiceDoesNotExist)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	mary := container.NewService()
	mary.SetConstructor(func() Person {
		return Person{}
	})
	mary.SetField("Name", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	// oops... we forgot to add the variable `mary` to the container
	// c.OverrideService("mary", mary)

	_, err := c.Get("mary")
	fmt.Println(err)

}
Output:

container.get("mary"): service does not exist
Example (GetTaggedBy)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	p1 := container.NewService()
	p1.SetValue(Person{})
	p1.SetField("Name", container.NewDependencyValue("person1"))
	p1.Tag("person", 0) // priority 0

	p2 := container.NewService()
	p2.SetValue(Person{})
	p2.SetField("Name", container.NewDependencyValue("person2"))
	p2.Tag("person", 1) // priority 1

	p3 := container.NewService()
	p3.SetValue(Person{})
	p3.SetField("Name", container.NewDependencyValue("person3"))
	p3.Tag("person", 2) // priority 2

	c := container.NewContainer()
	c.OverrideService("p1", p1)
	c.OverrideService("p2", p2)
	c.OverrideService("p3", p3)

	// it returns all services tagged by "person", sorted by the tag priority
	people, _ := c.GetTaggedBy("person")

	fmt.Println(people)

}
Output:

[{person3} {person2} {person1}]
Example (InvalidConstructorParameters)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Server struct {
	Host string
	Port int
}

func NewServer(host string, port int) *Server {
	return &Server{Host: host, Port: port}
}

func main() {
	s := container.NewService()
	// invalid arguments
	s.SetConstructor(
		NewServer,
		container.NewDependencyValue(nil),         // it should be a string!
		container.NewDependencyValue("localhost"), // it should be an int!
	)

	c := container.NewContainer()
	c.OverrideService("server", s)

	_, err := c.Get("server")
	fmt.Println(err)

}
Output:

container.get("server"): constructor: arg0: cannot cast `<nil>` to `string`
container.get("server"): constructor: arg1: cannot cast `string` to `int`
Example (ScopePrivate)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

func main() {
	i := 0

	num := container.NewService()
	num.SetConstructor(func() int {
		i++
		return i
	})
	num.ScopePrivate()

	c := container.NewContainer()
	c.OverrideService("number", num)

	first, _ := c.Get("number")
	second, _ := c.Get("number")

	// first is not equal to second, because the scope is private
	fmt.Println(first, second)

}
Output:

1 2
Example (ScopeShared)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

func main() {
	i := 0

	num := container.NewService()
	num.SetConstructor(func() int {
		i++
		return i
	})
	num.ScopeShared()

	c := container.NewContainer()
	c.OverrideService("number", num)

	first, _ := c.Get("number")
	second, _ := c.Get("number")

	// first is equal to second, because the scope is shared
	fmt.Println(first, second)

}
Output:

1 1
Example (Setter)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	mary := container.NewService()
	mary.SetConstructor(func() *Person { // we have to use a pointer, because we use a setter
		return &Person{}
	})
	mary.AppendCall("SetName", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	c.OverrideService("mary", mary)

	maryObject, _ := c.Get("mary")
	fmt.Println(maryObject)

}
Output:

&{Mary Jane}
Example (Simple)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

type People struct {
	People []Person
}

func main() {
	// create Mary Jane
	mary := container.NewService()
	mary.SetConstructor(func() Person {
		return Person{}
	})
	mary.SetField("Name", container.NewDependencyValue("Mary Jane"))
	mary.Tag("person", 1) // priority = 1, ladies first :)

	// create Peter Parker
	peter := container.NewService()
	peter.SetConstructor(func() Person {
		return Person{}
	})
	peter.SetField("Name", container.NewDependencyProvider(func() string {
		return "Peter Parker"
	}))
	peter.Tag("person", 0)

	// create "people"
	people := container.NewService()
	people.SetValue(People{})                                       // instead of providing a constructor, we can provide a value directly
	people.SetField("People", container.NewDependencyTag("person")) // fetch all objects tagged as "person", and assign them to the field "people"

	// create a container, and append all services there
	c := container.NewContainer()
	c.OverrideService("mary", mary)
	c.OverrideService("peter", peter)
	c.OverrideService("people", people)

	// instead of these 2 following lines,
	// you can write:
	//
	// peopleObject, _ := c.Get("people")
	var peopleObject People
	_ = c.CopyServiceTo("people", &peopleObject)

	fmt.Printf("%+v\n", peopleObject)

}
Output:

{People:[{Name:Mary Jane} {Name:Peter Parker}]}
Example (Wither)
package main

import (
	"fmt"

	"github.com/gomponents/gontainer-helpers/container"
)

type Person struct {
	Name string
}

func (p *Person) SetName(n string) {
	p.Name = n
}

func (p Person) WithName(n string) Person {
	p.Name = n
	return p
}

func main() {
	mary := container.NewService()
	mary.SetConstructor(func() Person {
		return Person{}
	})
	mary.AppendWither("WithName", container.NewDependencyValue("Mary Jane"))

	c := container.NewContainer()
	c.OverrideService("mary", mary)

	maryObject, _ := c.Get("mary")
	fmt.Println(maryObject)

}
Output:

{Mary Jane}

func NewParamContainer

func NewParamContainer() *paramContainer

Types

type DecoratorContext

type DecoratorContext struct {
	Tag       string
	ServiceID string
	Service   interface{}
}

type Dependency

type Dependency struct {
	// contains filtered or unexported fields
}

func NewDependencyProvider

func NewDependencyProvider(provider interface{}) Dependency

func NewDependencyService

func NewDependencyService(serviceID string) Dependency

NewDependencyService creates a Dependency to the given Service

func NewDependencyTag

func NewDependencyTag(tagID string) Dependency

NewDependencyTag creates a Dependency to the given tag

func NewDependencyValue

func NewDependencyValue(v interface{}) Dependency

NewDependencyValue creates a nil-Dependency, it does not depend on anything in the container

type Service

type Service struct {
	// contains filtered or unexported fields
}

func NewService

func NewService() Service

func (*Service) AppendCall

func (s *Service) AppendCall(method string, deps ...Dependency) *Service

func (*Service) AppendWither

func (s *Service) AppendWither(method string, deps ...Dependency) *Service

func (*Service) ScopeContextual

func (s *Service) ScopeContextual() *Service

func (*Service) ScopeDefault

func (s *Service) ScopeDefault() *Service

func (*Service) ScopePrivate

func (s *Service) ScopePrivate() *Service

func (*Service) ScopeShared

func (s *Service) ScopeShared() *Service

func (*Service) SetConstructor

func (s *Service) SetConstructor(fn interface{}, deps ...Dependency) *Service

func (*Service) SetField

func (s *Service) SetField(field string, dep Dependency) *Service

func (*Service) SetValue

func (s *Service) SetValue(v interface{}) *Service

func (*Service) Tag

func (s *Service) Tag(tag string, priority int) *Service

type SuperContainer

type SuperContainer struct {
	// contains filtered or unexported fields
}

func NewSuperContainer

func NewSuperContainer() *SuperContainer

func (SuperContainer) AddDecorator

func (c SuperContainer) AddDecorator(tag string, decorator interface{}, deps ...Dependency)

func (SuperContainer) CircularDeps

func (c SuperContainer) CircularDeps() error

func (SuperContainer) CopyServiceTo

func (c SuperContainer) CopyServiceTo(id string, dst interface{}) (err error)

CopyServiceTo gets or creates the desired service and copies it to the given pointer

var server *http.Server
container.CopyServiceTo("server", &server)

func (SuperContainer) Get

func (c SuperContainer) Get(id string) (result interface{}, err error)

func (SuperContainer) GetParam

func (p SuperContainer) GetParam(id string) (result interface{}, err error)

func (SuperContainer) GetTaggedBy

func (c SuperContainer) GetTaggedBy(tag string) (result []interface{}, err error)

func (SuperContainer) IsTaggedBy

func (c SuperContainer) IsTaggedBy(id string, tag string) bool

func (SuperContainer) OverrideParam

func (p SuperContainer) OverrideParam(id string, d Dependency)

func (SuperContainer) OverrideService

func (c SuperContainer) OverrideService(id string, s Service)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL