Skip to main content
Remy DI - Dependency Injection for Go
GitHub Go Docs Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Retrieving Multiple Elements

These functions retrieve all registered elements that match the requested type. This requires DuckTypeElements config to be enabled in the injector configuration.

Key Points:

  • šŸ“¦ Returns all matching implementations
  • šŸ¦† Requires DuckTypeElements: true in injector config
  • šŸ” Useful for plugin systems and service discovery

Prerequisites

Enable duck typing in the injector configuration:

1
inj := remy.NewInjector(remy.Config{DuckTypeElements: true})

GetAll

GetAll retrieves all registered elements that match the requested type and returns an error if something goes wrong.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
	"log"

	"github.com/wrapped-owls/goremy-di/remy"
)

type Service interface {
	DoSomething()
}

func main() {
	// Returns all services that implement the Service interface
	services, err := remy.GetAll[Service](injector)
	if err != nil {
		log.Fatal(err)
	}

	for _, service := range services {
		service.DoSomething()
	}
}

MustGetAll

MustGetAll panics if an error occurs or if DuckTypeElements is not enabled.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import (
	"github.com/wrapped-owls/goremy-di/remy"
)

func main() {
	services := remy.MustGetAll[Service](injector)
	// Panics if DuckTypeElements is not enabled or if an error occurs
	for _, service := range services {
		service.DoSomething()
	}
}

MaybeGetAll

MaybeGetAll returns an empty slice if an error occurs, allowing graceful handling of missing dependencies.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import (
	"github.com/wrapped-owls/goremy-di/remy"
)

func main() {
	services := remy.MaybeGetAll[Service](injector)
	// Returns empty slice if error occurs or DuckTypeElements is not enabled
	for _, service := range services {
		service.DoSomething()
	}
}

Use Cases

Plugin Systems

When you have multiple implementations of the same interface:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
	"log"

	"github.com/wrapped-owls/goremy-di/remy"
)

type Plugin interface {
	Name() string
	Execute()
}

func main() {
	// Register multiple plugins
	remy.RegisterInstance(injector, &PluginA{})
	remy.RegisterInstance(injector, &PluginB{})
	remy.RegisterInstance(injector, &PluginC{})

	// Retrieve all plugins
	plugins := remy.MustGetAll[Plugin](injector)
	for _, plugin := range plugins {
		log.Printf("Executing plugin: %s", plugin.Name())
		plugin.Execute()
	}
}

Service Discovery

Discover all services that implement a specific interface:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
	"log"

	"github.com/wrapped-owls/goremy-di/remy"
)

type HealthCheckable interface {
	HealthCheck() error
}

func main() {
	// All registered health-checkable services
	healthServices := remy.MustGetAll[HealthCheckable](injector)
	for _, service := range healthServices {
		if err := service.HealthCheck(); err != nil {
			log.Printf("Health check failed: %v", err)
		}
	}
}

Important Notes

  • Ambiguity: If you need a specific implementation, use tags instead of GetAll
  • Empty Results: GetAll may return an empty slice if no matches are found (this is not an error)