uber-go / dig

A reflection based dependency injection toolkit for Go.
https://go.uber.org/dig
MIT License
3.88k stars 206 forks source link

param: Search scopes during Build, support value groups #312

Closed abhinav closed 2 years ago

abhinav commented 2 years ago

This significantly changes how we instantiate dependencies for a constructor and adds support for value groups.

Previously, for each parameter of a constructor, we attempted to instantiate the value in every scope until one succeeded without dependency errors. Effectively:

for param in constructor
    for scope in scopes_to_root
        err = scope.instantiate(param)
        if err != missing_dependencies {
            return err
        }

This made the behavior less certain because we were relying on fuzzily matching errors.

With this change, we search the container for constructors as needed for singular parameters (paramSingle) and for value groups (paramGroupedSlice). Roughly:

for param in constructor
    switch param {
    case paramSingle:
        for scope in scopes_to_root {
            if scope.provides(param) {
                found = true
            }
        }
        // ...

    case paramGroupedSlice:
        for scope in scopes_to_root {
            providers.append(scope.providers_for(param))
        }

    default:
        // ...
    }

This is cleaner because it works by searching the container for what it needs rather than trying and letting it fail.

This includes a subtle change to constructorNode.Call: previously, when a constructor ran, its results were stored in the containerStore that it used to instantiate its dependencies. Now, results are stored in the containerStore (Scope) to which that constructor was provided. This works because the leaf param types (paramSingle and paramGroupedSlice) will search the scope tree to find the value.

codecov[bot] commented 2 years ago

Codecov Report

Merging #312 (97eae89) into master (08ad091) will decrease coverage by 0.07%. The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #312      +/-   ##
==========================================
- Coverage   98.61%   98.54%   -0.08%     
==========================================
  Files          19       19              
  Lines        1230     1233       +3     
==========================================
+ Hits         1213     1215       +2     
- Misses         10       11       +1     
  Partials        7        7              
Impacted Files Coverage Δ
constructor.go 100.00% <100.00%> (ø)
param.go 98.51% <100.00%> (-0.49%) :arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 08ad091...97eae89. Read the comment docs.