defval / di

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Change how Injected structs are tagged

chirino opened this issue · comments

Currently injected structs resolve using tag constraint like so:

type Parameters struct {
	di.Inject
	
	// use tag for the container to know that field need to be injected.
	Leader   *DatabaseConfig `type:"leader"`
	Follower *DatabaseConfig `type:"follower"`
}

But things start to break down if that same struct is used in other ways, for example marshalling:

type Parameters struct {
	di.Inject
	
	// use tag for the container to know that field need to be injected.
	Leader   *DatabaseConfig `type:"leader"   json:"leader"`
	Follower *DatabaseConfig `type:"follower" json:"follower"`
}

To avoid conflicting with other libs that also use tags to provide features on structs, I propose that we change how goava/di looks for struct tags that look like this instead:

type Parameters struct {
	di.Inject
	
	// use tag for the container to know that field need to be injected.
	Leader   *DatabaseConfig `di:"type=leader"`
	Follower *DatabaseConfig `di:"type=follower"`
}

Hi @chirino! This change looks rational.
But since we use this library in most of our services, we don't want to lose backward compatibility.
Maybe it can be implemented like this: first we look for a di: tag, and if we find it, we will use comma-separated key=value pairs from it as our di tags (e.g.: di:"type=leader,foo=bar"). If no di: tag is present on the field, we will parse struct tags like before.

Sounds good to me. Should we print warning messages when the old style is found to encourage users to convert?

I think we should, using global tracer for messages.
Also there are skip and optional tags, do you think we should move them also inside di: tag or leave them where they are?

Yes, and perhaps to avoid mixing them up with user defined tags (which have a = in them) it should just be:
di:"skip" or di:"optional"