Skip to content

Commit 6773c0f

Browse files
committed
feat: resolve by token
1 parent 06b7339 commit 6773c0f

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

pkg/container/container.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ import (
1111

1212
type Container struct {
1313
graph.Graph[resolver.DependencyResolver[any]]
14-
typeIndex map[reflect.Type]*graph.Node[resolver.DependencyResolver[any]]
15-
connected bool
14+
typeIndex map[reflect.Type]*graph.Node[resolver.DependencyResolver[any]]
15+
tokenIndex map[string]*graph.Node[resolver.DependencyResolver[any]]
16+
connected bool
1617
}
1718

1819
func New() *Container {
1920
return &Container{
20-
Graph: graph.NewGraph[resolver.DependencyResolver[any]](),
21-
typeIndex: make(map[reflect.Type]*graph.Node[resolver.DependencyResolver[any]]),
21+
Graph: graph.NewGraph[resolver.DependencyResolver[any]](),
22+
typeIndex: make(map[reflect.Type]*graph.Node[resolver.DependencyResolver[any]]),
23+
tokenIndex: make(map[string]*graph.Node[resolver.DependencyResolver[any]]),
2224
}
2325
}
2426

@@ -45,6 +47,28 @@ func (c *Container) AddDependency(res any) error {
4547
return nil
4648
}
4749

50+
func (c *Container) AddTokenDependency(token string, res any) error {
51+
c.connected = false
52+
if !resolver.IsValid(res) {
53+
return errors.New("invalid resolver")
54+
}
55+
56+
builder := resolver.DependencyResolver[any]{
57+
Resolver: res,
58+
}
59+
60+
_, exists := c.tokenIndex[token]
61+
if exists {
62+
return fmt.Errorf("dependency for token type already exists: %s", token)
63+
}
64+
65+
node := graph.NewNode(builder)
66+
c.Add(node)
67+
c.tokenIndex[token] = node
68+
69+
return nil
70+
}
71+
4872
func (c *Container) AddDependencies(resolvers ...any) error {
4973
c.connected = false
5074
for _, res := range resolvers {
@@ -157,3 +181,26 @@ func (c Container) resolve(t reflect.Type) (resolvedValue reflect.Value, err err
157181

158182
return resolver.Execute(dependencyResolver, inputArgs)
159183
}
184+
185+
func (c Container) resolveToken(token string) (resolvedValue reflect.Value, err error) {
186+
node, ok := c.tokenIndex[token]
187+
if !ok {
188+
err = fmt.Errorf("dependency not found for token %s", token)
189+
return
190+
}
191+
192+
dependencyResolver := node.Val
193+
inputTypes := dependencyResolver.Input()
194+
inputArgs := []reflect.Value{}
195+
196+
for _, inputType := range inputTypes {
197+
arg, err := c.resolve(inputType)
198+
if err != nil {
199+
return resolvedValue, err
200+
}
201+
202+
inputArgs = append(inputArgs, arg)
203+
}
204+
205+
return resolver.Execute(dependencyResolver, inputArgs)
206+
}

pkg/container/container_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,18 @@ func TestFill(t *testing.T) {
8484
err = cont.Fill(&deps)
8585
require.NoError(t, err, "struct should be filled correctly")
8686
}
87+
88+
func TestResolveToken(t *testing.T) {
89+
cont := container.New()
90+
91+
dependantResolver := func() *bytes.Buffer {
92+
return bytes.NewBuffer([]byte{})
93+
}
94+
95+
err := cont.AddTokenDependency("buffer", dependantResolver)
96+
require.NoError(t, err)
97+
98+
buf, err := container.ResolveToken[*bytes.Buffer](cont, "buffer")
99+
require.NoError(t, err)
100+
require.NotNil(t, buf)
101+
}

pkg/container/resolve.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,24 @@ func Resolve[T any](c *Container) (T, error) {
2525

2626
return dependency, err
2727
}
28+
29+
func ResolveToken[T any](c *Container, token string) (T, error) {
30+
var dependency T
31+
_, err := c.DetectCircularDependencies()
32+
if err != nil {
33+
return dependency, err
34+
}
35+
36+
resolvedValue, err := c.resolveToken(token)
37+
if err != nil {
38+
return dependency, err
39+
}
40+
41+
var ok bool
42+
dependency, ok = resolvedValue.Interface().(T)
43+
if !ok {
44+
err = fmt.Errorf("cannot convert returned value into %s", reflect.TypeFor[T]().String())
45+
}
46+
47+
return dependency, err
48+
}

0 commit comments

Comments
 (0)