Add ParamTag[T] and ResultTag[T] type-targeted annotations#1289
Draft
destel wants to merge 6 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adding a parameter to a constructor in fx is usually a free change - the DI graph wires it from an existing provider. That stops being free when there are multiple providers of the same type: now we have to tell fx which one to pick by attaching a name to the parameter.
One way to do this is
fx.Annotate. In typical fx codebases,fx.Annotatecalls live in module assembly files, far from the constructors they annotate. This makes positional tagging viafx.ParamTags/fx.ResultTagserror-prone:This PR is a proposal to add two new functions, fx.ParamTag[T] and fx.ResultTag[T], that let us tag constructor params/results based on their type rather than position:
If
NewServiceparameters change, the second form either keeps working, or fails with a clear error at apply time if the targeted type is gone.When there are multiple parameters of the same type, it's possible to target a specific one with the second argument passed to
fx.ParamTag:I'm proposing 1-based indexing here - it matches how we naturally speak about function arguments (1st DB, 2nd DB, not 0th DB).
Tagging of constructor results is done in a very similar way with
fx.ResultTag[T].Implementation
The change is minimal and backwards compatible. Roughly speaking, under the hood type-targeted annotations are converted into positional ones and delegated to the stock
fx.ParamTags/fx.ResultTags. All new behaviors are covered with tests.Alternative API designs
I picked a simple API design that stays as close as possible to existing fx functions, but I'm open to other shapes. Some ideas I thought of:
fx.ParamName[T],fx.ParamGroup[T],fx.ResultName[T],fx.ResultGroup[T]and groups