Skip to main content

Multiple Implementations

In Ore, you could also register multiple implementations of the same service (ie. interface)

//simpleCounter
ore.RegisterFunc[Counter](ore.Scoped, func(ctx context.Context) (Counter, context.Context) {
return &simpleCounter{}, ctx
})

//atomicCounter
ore.RegisterFunc[Counter](ore.Scoped, func(ctx context.Context) (Counter, context.Context) {
return &atomicCounter{}, ctx
})

//quantumCounter
ore.RegisterFunc[Counter](ore.Transient, func(ctx context.Context) (Counter, context.Context) {
return &quantumCounter{}, ctx
})

//rgbCounter
ore.RegisterCreator[Counter](ore.Singleton, &rgbCounter{})

here we've registered 4 different implementations for Counter service in all ways and lifetimes possible.

now let's resolve Service using ore.GetList:

allCounters, ctx := ore.GetList[Counter](context.Background())

fmt.Println(len(allCounters)) // outputs 4

for _, counter := range allCounters {
fmt.Println(counter.AddOne())
}

resolving only one implementation:

counter, ctx := ore.Get[Counter](context.Background())

you'll notice that counter is of type rgbCounter{}, because by default, Ore will resolve only the last registered implementation for Service when ore.Get is called.

Multiple Keyed Implementations​

You could also register multiple keyed implementations of the same service :

//simpleCounter
ore.RegisterKeyedFunc[Counter](ore.Scoped, func(ctx context.Context) (Counter, context.Context) {
return &simpleCounter{}, ctx
}, "simple")

//atomicCounter
ore.RegisterKeyedFunc[Counter](ore.Scoped, func(ctx context.Context) (Counter, context.Context) {
return &atomicCounter{}, ctx
}, "exotic")

//rgbCounter
ore.RegisterKeyedCreator[Counter](ore.Singleton, &rgbCounter{}, "exotic")

//quantumCounter
ore.RegisterKeyedFunc[Counter](ore.Transient, func(ctx context.Context) (Counter, context.Context) {
return &quantumCounter{}, ctx
}, "exotic")

let's now resolve a list of implementation of the service by key:

exoticCounters, ctx := ore.GetKeyedList[Counter](context.Background(), "exotic")
fmt.Println(len(exoticCounters)) // outputs: 3

nonKeyedCounters, ctx := ore.GetList[Counter](context.Background())
fmt.Println(len(nonKeyedCounters)) // outputs: 0

simpleCounters, ctx := ore.GetKeyedList[Counter](context.Background(), "simple")
fmt.Println(len(simpleCounters)) // outputs: 1

let's see what happens when we try to resolve a single implementation:

exoticCounter, ctx := ore.GetKeyed[Counter](context.Background(), "exotic")
// `exoticCounter` is of type `quantumCounter{}`

simpleCounter, ctx := ore.GetKeyed[Counter](context.Background(), "simple")
// `simpleCounter` is of type `simpleCounter{}`


counter, ctx := ore.Get[Counter](context.Background())
// this will panic, because there is no non-keyed implementation for `Counter`


awesomeCounter, ctx := ore.GetKeyed[Counter](context.Background(), "awesome")
// this will panic, because there is no implementation for `Counter` with key `awesome`