defval / di

🛠 A full-featured dependency injection container for go programming language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

container.Resolve() doesn't create signleton when dependency requested via intermidiate constructor

erickskrauch opened this issue · comments

The title :)

I can't make Go's playground to run this code since it's using a version of the project without Container available in the dependency graph.

package main

import (
	"log"

	"github.com/goava/di"
)

type Interface interface {
	Do()
}

type Implementation1 struct{}

func (d Implementation1) Do() {}

type Implementation2 struct{}

func (d Implementation2) Do() {}

func newFactory(container *di.Container) (Interface, error) {
	// Some decision logic which implementation to choose
	var implementation *Implementation1
	err := container.Resolve(&implementation)
	if err != nil {
		return nil, err
	}

	return implementation, nil
}

func newImplementation1() *Implementation1 {
	println("called implementation 1")
	return &Implementation1{}
}

func newImplementation2() *Implementation2 {
	println("called implementation 2")
	return &Implementation2{}
}

func main() {
	container, err := di.New(
		di.Provide(newFactory),
		di.Provide(newImplementation1),
		di.Provide(newImplementation2),
	)
	if err != nil {
		log.Fatal(err)
	}

	var implementationByFactory Interface
	err = container.Resolve(&implementationByFactory)
	if err != nil {
		log.Fatal(err)
	}

	var directImplementation *Implementation1
	err = container.Resolve(&directImplementation)
	if err != nil {
		log.Fatal(err)
	}
}

Output:

called implementation 1
called implementation 1

But expected only one call.

Fixed in 1d9af1f.

The problem is only in the master branch. It's cool that you found it 👏.