-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: remove DIContainer abstraction (#196)
* fix: Optimized debug message * refactor: remove di abstraction * test: fix failed tests * fix: comment Co-authored-by: Trock <g_trock@163.com>
- Loading branch information
Showing
13 changed files
with
274 additions
and
198 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,10 @@ | ||
package contract | ||
|
||
// DIProvider is an interface that models a container to which users can add | ||
// dependencies. See di.Graph for the implementation requirement. | ||
type DIProvider interface { | ||
Provide(constructor interface{}) error | ||
} | ||
|
||
// DIInvoker is an interface that models a container to which users can fetch | ||
// dependencies. See di.Graph for the implementation requirement. | ||
type DIInvoker interface { | ||
Invoke(function interface{}) error | ||
} | ||
|
||
// DIPopulator is an interface that models a container to which users can fetch | ||
// dependencies. It is an syntax sugar to DIInvoker. See di.Graph for the | ||
// dependencies. It is a syntax sugar to dig.Container. See dig.Container for the | ||
// implementation requirement. | ||
type DIPopulator interface { | ||
// Populate is just another way of fetching dependencies from container. It | ||
// accepts a ptr to target, and populates the target from the container. | ||
Populate(target interface{}) error | ||
} | ||
|
||
// DIContainer is a container roughly modeled after dig.Container. | ||
type DIContainer interface { | ||
DIProvider | ||
DIInvoker | ||
} |
This file contains 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
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package di | ||
|
||
import ( | ||
"reflect" | ||
|
||
"go.uber.org/dig" | ||
) | ||
|
||
// OptionalProvider is a struct with constructor and dig options. When | ||
// OptionalProvider is used as the element in di.Deps, the options are applied to | ||
// the inner dig.Container automatically. | ||
type OptionalProvider struct { | ||
Constructor interface{} | ||
Options []dig.ProvideOption | ||
} | ||
|
||
// LocationForPC sets the constructor pointer to a specified location. Use this | ||
// Options to reduce vague debug message when constructor are made by | ||
// reflect.makeFunc. For example: | ||
// LocationForPC(reflect.makeFunc(...), reflect.ValueOf(realConstructor).Pointer()) | ||
func LocationForPC(constructor interface{}, pc uintptr) interface{} { | ||
if op, ok := constructor.(OptionalProvider); ok { | ||
op.Options = append(op.Options, dig.LocationForPC(pc)) | ||
return op | ||
} | ||
return OptionalProvider{ | ||
Constructor: constructor, | ||
Options: []dig.ProvideOption{dig.LocationForPC(pc)}, | ||
} | ||
} | ||
|
||
// As constructs the instance and bind it to another interface. As means to be used as an argument to graph.Provide. | ||
// For example: | ||
// As(MyConstructor, new(MyAbstractInterface)) | ||
func As(constructor interface{}, as interface{}) interface{} { | ||
if op, ok := constructor.(OptionalProvider); ok { | ||
op.Options = append(op.Options, dig.As(as)) | ||
return op | ||
} | ||
return OptionalProvider{ | ||
Constructor: constructor, | ||
Options: []dig.ProvideOption{dig.As(as)}, | ||
} | ||
} | ||
|
||
// Name constructs a named instance. Name means to be used as an argument to graph.Provide. | ||
// For example: | ||
// Name(MyConstructor, "foo") | ||
func Name(constructor interface{}, name string) interface{} { | ||
if op, ok := constructor.(OptionalProvider); ok { | ||
op.Options = append(op.Options, dig.Name(name)) | ||
return op | ||
} | ||
return OptionalProvider{ | ||
Constructor: constructor, | ||
Options: []dig.ProvideOption{dig.Name(name)}, | ||
} | ||
} | ||
|
||
// Bind binds a type to another. Useful when binding implementation to | ||
// interfaces. The arguments should be a ptr to the binding types, rather than | ||
// the types themselves. For example: | ||
// Bind(new(MyConcreteStruct), new(MyAbstractInterface)) | ||
func Bind(from interface{}, to interface{}) interface{} { | ||
fromTypes := []reflect.Type{reflect.TypeOf(from).Elem()} | ||
toTypes := []reflect.Type{reflect.TypeOf(to).Elem()} | ||
fnType := reflect.FuncOf(fromTypes, toTypes, false /* variadic */) | ||
fn := reflect.MakeFunc(fnType, func(args []reflect.Value) []reflect.Value { | ||
return args | ||
}) | ||
return fn.Interface() | ||
} |
Oops, something went wrong.