Skip to content
This repository was archived by the owner on Jan 18, 2021. It is now read-only.

Commit

Permalink
Allow inject.As without name
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim Bovtunov committed Jun 12, 2019
1 parent 300f140 commit 333c737
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
39 changes: 34 additions & 5 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,17 +449,46 @@ func TestContainer_ProvideAs(t *testing.T) {
require.Equal(t, "test", addr.(*net.TCPAddr).Zone)
})

t.Run("provide duplicate interface without name", func(t *testing.T) {
_, err := inject.New(
t.Run("extract no unique interface instance", func(t *testing.T) {
tcpAddr := &net.TCPAddr{}
udpAddr := &net.UDPAddr{}

container, err := inject.New(
inject.Provide(func() *net.TCPAddr {
return &net.TCPAddr{}
return tcpAddr
}, inject.As(new(net.Addr))),
inject.Provide(func() *net.UDPAddr {
return &net.UDPAddr{}
return udpAddr
}, inject.As(new(net.Addr))),
)

require.NoError(t, err)

var addr net.Addr
require.EqualError(t, container.Extract(&addr), "could not extract net.Addr: you have several instances of this interface type, use WithName() to identify it")
})

t.Run("try provide no unique interface instance", func(t *testing.T) {
tcpAddr := &net.TCPAddr{}
udpAddr := &net.UDPAddr{}

container, err := inject.New(
inject.Provide(func() *net.TCPAddr {
return tcpAddr
}, inject.As(new(net.Addr))),
inject.Provide(func() *net.UDPAddr {
return udpAddr
}, inject.As(new(net.Addr))),
inject.Provide(func(addr net.Addr) bool {
return true
}),
)

require.EqualError(t, err, "could not compile container: net.Addr: use named definition if you have several instances of the same type")
require.NoError(t, err)

var b bool
require.EqualError(t, container.Extract(&b), "could not extract net.Addr: you have several instances of this interface type, use WithName() to identify it")

})

t.Run("provide as named interface", func(t *testing.T) {
Expand Down
9 changes: 7 additions & 2 deletions internal/graph/node_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,20 @@ func NewInterfaceNode(name string, node *ProviderNode, iface interface{}) (_ *In

// InterfaceNode
type InterfaceNode struct {
key Key
node *ProviderNode
key Key
node *ProviderNode
multiple bool
}

func (n *InterfaceNode) Key() Key {
return n.key
}

func (n *InterfaceNode) Extract(target reflect.Value) (err error) {
if n.multiple {
return errors.Errorf("could not extract %s: you have several instances of this interface type, use WithName() to identify it", n.Key())
}

if !target.Type().Implements(n.key.Type) {
return errors.Errorf("%s not implement %s", target.Type(), n.key.Type)
}
Expand Down
8 changes: 7 additions & 1 deletion internal/graph/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ type Storage struct {

// Check
func (s *Storage) Add(node Node) (err error) {
if _, ok := s.nodes[node.Key()]; ok {
if n, ok := s.nodes[node.Key()]; ok {
if ifaceNode, ok := n.(*InterfaceNode); ok {
ifaceNode.multiple = true

return nil
}

return errors.Errorf("%s: use named definition if you have several instances of the same type", node.Key())
}

Expand Down

0 comments on commit 333c737

Please sign in to comment.