diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-11 21:12:57 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-11 21:12:57 -0600 |
| commit | 60440f90dca28e99a31dd328c5f6d5dc0f9b6a2e (patch) | |
| tree | 2f54adf55086516f162f0a55a5347e6b25f7f176 /vendor/github.com/golobby/container | |
| parent | 05ca9b8d3a9c7203a3a3b590beaa400900bd9007 (diff) | |
chore: vendor go dependencies
Diffstat (limited to 'vendor/github.com/golobby/container')
| -rw-r--r-- | vendor/github.com/golobby/container/v3/.gitignore | 3 | ||||
| -rw-r--r-- | vendor/github.com/golobby/container/v3/LICENSE | 21 | ||||
| -rw-r--r-- | vendor/github.com/golobby/container/v3/README.md | 321 | ||||
| -rw-r--r-- | vendor/github.com/golobby/container/v3/container.go | 299 | ||||
| -rw-r--r-- | vendor/github.com/golobby/container/v3/global.go | 69 | ||||
| -rw-r--r-- | vendor/github.com/golobby/container/v3/must.go | 85 |
6 files changed, 798 insertions, 0 deletions
diff --git a/vendor/github.com/golobby/container/v3/.gitignore b/vendor/github.com/golobby/container/v3/.gitignore new file mode 100644 index 0000000..bc9f04f --- /dev/null +++ b/vendor/github.com/golobby/container/v3/.gitignore @@ -0,0 +1,3 @@ +/.idea +/build +/vendor diff --git a/vendor/github.com/golobby/container/v3/LICENSE b/vendor/github.com/golobby/container/v3/LICENSE new file mode 100644 index 0000000..6605b32 --- /dev/null +++ b/vendor/github.com/golobby/container/v3/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 GoLobby + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/golobby/container/v3/README.md b/vendor/github.com/golobby/container/v3/README.md new file mode 100644 index 0000000..0c30e9f --- /dev/null +++ b/vendor/github.com/golobby/container/v3/README.md @@ -0,0 +1,321 @@ +[](https://pkg.go.dev/github.com/golobby/container) +[](https://github.com/golobby/container/actions/workflows/ci.yml) +[](https://github.com/golobby/container/actions/workflows/codeql-analysis.yml) +[](https://goreportcard.com/report/github.com/golobby/container) +[](https://coveralls.io/github/golobby/container?branch=master) +[](https://github.com/avelino/awesome-go) + +# Container +GoLobby Container is a lightweight yet powerful IoC (dependency injection) container for Go projects. +It's built neat, easy-to-use, and performance-in-mind to be your ultimate requirement. + +Features: +- Singleton and Transient bindings +- Named dependencies (bindings) +- Resolve by functions, variables, and structs +- Must helpers that convert errors to panics +- Optional lazy loading of bindings +- Global instance for small applications +- 100% Test coverage! + +## Documentation +### Required Go Versions +It requires Go `v1.11` or newer versions. + +### Installation +To install this package, run the following command in your project directory. + +```bash +go get github.com/golobby/container/v3 +``` + +Next, include it in your application: + +```go +import "github.com/golobby/container/v3" +``` + +### Introduction +GoLobby Container is used to bind abstractions to their implementations. +Binding is the process of introducing appropriate concretes (implementations) of abstractions to an IoC container. +In this process, you also determine the resolving type, singleton or transient. +In singleton bindings, the container provides an instance once and returns it for all the requests. +In transient bindings, the container always returns a brand-new instance for each request. +After the binding process, you can ask the IoC container to make the appropriate implementation of the abstraction that your code needs. +Then your code will depend on abstractions, not implementations! + +### Quick Start +The following example demonstrates a simple binding and resolving. + +```go +// Bind Config interface to JsonConfig struct +err := container.Singleton(func() Config { + return &JsonConfig{...} +}) + +var c Config +err := container.Resolve(&c) +// `c` will be the instance of JsonConfig +``` + +### Typed Binding +#### Singleton +The following snippet expresses singleton binding. + +```go +err := container.Singleton(func() Abstraction { + return Implementation +}) + +// If you might return an error... + +err := container.Singleton(func() (Abstraction, error) { + return Implementation, nil +}) +``` + +It takes a resolver (function) whose return type is the abstraction and the function body returns the concrete (implementation). + +The example below shows a singleton binding. + +```go +err := container.Singleton(func() Database { + return &MySQL{} +}) +``` + +#### Transient +The example below shows a transient binding. + +```go +err := container.Transient(func() Shape { + return &Rectangle{} +}) +``` + +### Named Bindings +You may have different concretes for an abstraction. +In this case, you can use named bindings instead of typed bindings. +Named bindings take the dependency name into account as well. +The rest is similar to typed bindings. +The following examples demonstrate some named bindings. + +```go +// Singleton +err := container.NamedSingleton("square", func() Shape { + return &Rectangle{} +}) +err := container.NamedSingleton("rounded", func() Shape { + return &Circle{} +}) + +// Transient +err := container.NamedTransient("sql", func() Database { + return &MySQL{} +}) +err := container.NamedTransient("noSql", func() Database { + return &MongoDB{} +}) +``` + +### Resolver Errors + +The process of creating concrete (resolving) might face an error. +In this case, you can return the error as the second return value like the example below. + +```go +err := container.Transient(func() (Shape, error) { + return nil, errors.New("my-app: cannot create a Shape implementation") +}) +``` + +It could be applied to other binding types. + +### Resolving +Container resolves the dependencies with the `Resolve()`, `Call()`, and `Fill()` methods. + +#### Using References +The `Resolve()` method takes reference of the abstraction type and fills it with the appropriate concrete. + +```go +var a Abstraction +err := container.Resolve(&a) +// `a` will be an implementation of the Abstraction +``` + +Example of resolving using references: + +```go +var m Mailer +err := container.Resolve(&m) +// `m` will be an implementation of the Mailer interface +m.Send("contact@miladrahimi.com", "Hello Milad!") +``` + +Example of named-resolving using references: + +```go +var s Shape +err := container.NamedResolve(&s, "rounded") +// `s` will be an implementation of the Shape that named rounded +``` + +#### Using Closures +The `Call()` method takes a receiver (function) with arguments of abstractions you need. +It calls it with parameters of appropriate concretes. + +```go +err := container.Call(func(a Abstraction) { + // `a` will be an implementation of the Abstraction +}) +``` + +Example of resolving using closures: + +```go +err := container.Call(func(db Database) { + // `db` will be an implementation of the Database interface + db.Query("...") +}) +``` + +You can also resolve multiple abstractions like the following example: + +```go +err := container.Call(func(db Database, s Shape) { + db.Query("...") + s.Area() +}) +``` + +You are able to raise an error in your receiver function, as well. + +```go +err := container.Call(func(db Database) error { + return db.Ping() +}) +// err could be `db.Ping()` error. +``` + +Caution: The `Call()` method does not support named bindings. + +#### Using Structs +The `Fill()` method takes a struct (pointer) and resolves its fields. + +The example below expresses how the `Fill()` method works. + +```go +type App struct { + mailer Mailer `container:"type"` + sql Database `container:"name"` + noSql Database `container:"name"` + other int +} + +myApp := App{} + +err := container.Fill(&myApp) + +// [Typed Bindings] +// `myApp.mailer` will be an implementation of the Mailer interface + +// [Named Bindings] +// `myApp.sql` will be a sql implementation of the Database interface +// `myApp.noSql` will be a noSql implementation of the Database interface + +// `myApp.other` will be ignored since it has no `container` tag +``` + +#### Binding time +You can resolve dependencies at the binding time if you need previous dependencies for the new one. + +The following example shows resolving dependencies at binding time. + +```go +// Bind Config to JsonConfig +err := container.Singleton(func() Config { + return &JsonConfig{...} +}) + +// Bind Database to MySQL +err := container.Singleton(func(c Config) Database { + // `c` will be an instance of `JsonConfig` + return &MySQL{ + Username: c.Get("DB_USERNAME"), + Password: c.Get("DB_PASSWORD"), + } +}) +``` + +### Standalone Instance +By default, the Container keeps your bindings in the global instance. +Sometimes you may want to create a standalone instance for a part of your application. +If so, create a standalone instance like the example below. + +```go +c := container.New() + +err := c.Singleton(func() Database { + return &MySQL{} +}) + +err := c.Call(func(db Database) { + db.Query("...") +}) +``` + +The rest stays the same. +The global container is still available. + +### Must Helpers + +You might believe that the container shouldn't raise any error and/or you prefer panics. +In this case, Must helpers are for you. +Must helpers are global methods that panic instead of returning errors. + +```go +c := container.New() +// Global instance: +// c := container.Global + +container.MustSingleton(c, func() Shape { + return &Circle{a: 13} +}) + +container.MustCall(c, func(s Shape) { + // ... +}) + +// Other Must Helpers: +// container.MustSingleton() +// container.MustSingletonLazy() +// container.MustNamedSingleton() +// container.MustNamedSingletonLazy() +// container.MustTransient() +// container.MustTransientLazy() +// container.MustNamedTransient() +// container.MustNamedTransientLazy() +// container.MustCall() +// container.MustResolve() +// container.MustNamedResolve() +// container.MustFill() +``` + +### Lazy Binding +Both the singleton and transient binding calls have a lazy version. +Lazy versions defer calling the provided resolver function until the first call. +For singleton bindings, It calls the resolver function only once and stores the result. + +Lazy binding methods: +* `container.SingletonLazy()` +* `container.NamedSingletonLazy()` +* `container.TransientLazy()` +* `container.NamedTransientLazy()` + +### Performance +The package Container inevitably uses reflection for binding and resolving processes. +If performance is a concern, try to bind and resolve the dependencies where it runs only once, like the main and init functions. + +## License + +GoLobby Container is released under the [MIT License](http://opensource.org/licenses/mit-license.php). diff --git a/vendor/github.com/golobby/container/v3/container.go b/vendor/github.com/golobby/container/v3/container.go new file mode 100644 index 0000000..d97ba2d --- /dev/null +++ b/vendor/github.com/golobby/container/v3/container.go @@ -0,0 +1,299 @@ +// Package container is a lightweight yet powerful IoC container for Go projects. +// It provides an easy-to-use interface and performance-in-mind container to be your ultimate requirement. +package container + +import ( + "errors" + "fmt" + "reflect" + "unsafe" +) + +// binding holds a resolver and a concrete (if already resolved). +// It is the break for the Container wall! +type binding struct { + resolver interface{} // resolver is the function that is responsible for making the concrete. + concrete interface{} // concrete is the stored instance for singleton bindings. + isSingleton bool // isSingleton is true if the binding is a singleton. +} + +// make resolves the binding if needed and returns the resolved concrete. +func (b *binding) make(c Container) (interface{}, error) { + if b.concrete != nil { + return b.concrete, nil + } + + retVal, err := c.invoke(b.resolver) + if b.isSingleton { + b.concrete = retVal + } + + return retVal, err +} + +// Container holds the bindings and provides methods to interact with them. +// It is the entry point in the package. +type Container map[reflect.Type]map[string]*binding + +// New creates a new concrete of the Container. +func New() Container { + return make(Container) +} + +// bind maps an abstraction to concrete and instantiates if it is a singleton binding. +func (c Container) bind(resolver interface{}, name string, isSingleton bool, isLazy bool) error { + reflectedResolver := reflect.TypeOf(resolver) + if reflectedResolver.Kind() != reflect.Func { + return errors.New("container: the resolver must be a function") + } + + if reflectedResolver.NumOut() > 0 { + if _, exist := c[reflectedResolver.Out(0)]; !exist { + c[reflectedResolver.Out(0)] = make(map[string]*binding) + } + } + + if err := c.validateResolverFunction(reflectedResolver); err != nil { + return err + } + + var concrete interface{} + if !isLazy { + var err error + concrete, err = c.invoke(resolver) + if err != nil { + return err + } + } + + if isSingleton { + c[reflectedResolver.Out(0)][name] = &binding{resolver: resolver, concrete: concrete, isSingleton: isSingleton} + } else { + c[reflectedResolver.Out(0)][name] = &binding{resolver: resolver, isSingleton: isSingleton} + } + + return nil +} + +func (c Container) validateResolverFunction(funcType reflect.Type) error { + retCount := funcType.NumOut() + + if retCount == 0 || retCount > 2 { + return errors.New("container: resolver function signature is invalid - it must return abstract, or abstract and error") + } + + resolveType := funcType.Out(0) + for i := 0; i < funcType.NumIn(); i++ { + if funcType.In(i) == resolveType { + return fmt.Errorf("container: resolver function signature is invalid - depends on abstract it returns") + } + } + + return nil +} + +// invoke calls a function and its returned values. +// It only accepts one value and an optional error. +func (c Container) invoke(function interface{}) (interface{}, error) { + arguments, err := c.arguments(function) + if err != nil { + return nil, err + } + + values := reflect.ValueOf(function).Call(arguments) + if len(values) == 2 && values[1].CanInterface() { + if err, ok := values[1].Interface().(error); ok { + return values[0].Interface(), err + } + } + return values[0].Interface(), nil +} + +// arguments returns the list of resolved arguments for a function. +func (c Container) arguments(function interface{}) ([]reflect.Value, error) { + reflectedFunction := reflect.TypeOf(function) + argumentsCount := reflectedFunction.NumIn() + arguments := make([]reflect.Value, argumentsCount) + + for i := 0; i < argumentsCount; i++ { + abstraction := reflectedFunction.In(i) + if concrete, exist := c[abstraction][""]; exist { + instance, err := concrete.make(c) + if err != nil { + return nil, err + } + arguments[i] = reflect.ValueOf(instance) + } else { + return nil, errors.New("container: no concrete found for: " + abstraction.String()) + } + } + + return arguments, nil +} + +// Reset deletes all the existing bindings and empties the container. +func (c Container) Reset() { + for k := range c { + delete(c, k) + } +} + +// Singleton binds an abstraction to concrete in singleton mode. +// It takes a resolver function that returns the concrete, and its return type matches the abstraction (interface). +// The resolver function can have arguments of abstraction that have been declared in the Container already. +func (c Container) Singleton(resolver interface{}) error { + return c.bind(resolver, "", true, false) +} + +// SingletonLazy binds an abstraction to concrete lazily in singleton mode. +// The concrete is resolved only when the abstraction is resolved for the first time. +// It takes a resolver function that returns the concrete, and its return type matches the abstraction (interface). +// The resolver function can have arguments of abstraction that have been declared in the Container already. +func (c Container) SingletonLazy(resolver interface{}) error { + return c.bind(resolver, "", true, true) +} + +// NamedSingleton binds a named abstraction to concrete in singleton mode. +func (c Container) NamedSingleton(name string, resolver interface{}) error { + return c.bind(resolver, name, true, false) +} + +// NamedSingleton binds a named abstraction to concrete lazily in singleton mode. +// The concrete is resolved only when the abstraction is resolved for the first time. +func (c Container) NamedSingletonLazy(name string, resolver interface{}) error { + return c.bind(resolver, name, true, true) +} + +// Transient binds an abstraction to concrete in transient mode. +// It takes a resolver function that returns the concrete, and its return type matches the abstraction (interface). +// The resolver function can have arguments of abstraction that have been declared in the Container already. +func (c Container) Transient(resolver interface{}) error { + return c.bind(resolver, "", false, false) +} + +// TransientLazy binds an abstraction to concrete lazily in transient mode. +// Normally the resolver will be called during registration, but that is skipped in lazy mode. +// It takes a resolver function that returns the concrete, and its return type matches the abstraction (interface). +// The resolver function can have arguments of abstraction that have been declared in the Container already. +func (c Container) TransientLazy(resolver interface{}) error { + return c.bind(resolver, "", false, true) +} + +// NamedTransient binds a named abstraction to concrete lazily in transient mode. +func (c Container) NamedTransient(name string, resolver interface{}) error { + return c.bind(resolver, name, false, false) +} + +// NamedTransient binds a named abstraction to concrete in transient mode. +// Normally the resolver will be called during registration, but that is skipped in lazy mode. +func (c Container) NamedTransientLazy(name string, resolver interface{}) error { + return c.bind(resolver, name, false, true) +} + +// Call takes a receiver function with one or more arguments of the abstractions (interfaces). +// It invokes the receiver function and passes the related concretes. +func (c Container) Call(function interface{}) error { + receiverType := reflect.TypeOf(function) + if receiverType == nil || receiverType.Kind() != reflect.Func { + return errors.New("container: invalid function") + } + + arguments, err := c.arguments(function) + if err != nil { + return err + } + + result := reflect.ValueOf(function).Call(arguments) + + if len(result) == 0 { + return nil + } else if len(result) == 1 && result[0].CanInterface() { + if result[0].IsNil() { + return nil + } + if err, ok := result[0].Interface().(error); ok { + return err + } + } + + return errors.New("container: receiver function signature is invalid") +} + +// Resolve takes an abstraction (reference of an interface type) and fills it with the related concrete. +func (c Container) Resolve(abstraction interface{}) error { + return c.NamedResolve(abstraction, "") +} + +// NamedResolve takes abstraction and its name and fills it with the related concrete. +func (c Container) NamedResolve(abstraction interface{}, name string) error { + receiverType := reflect.TypeOf(abstraction) + if receiverType == nil { + return errors.New("container: invalid abstraction") + } + + if receiverType.Kind() == reflect.Ptr { + elem := receiverType.Elem() + + if concrete, exist := c[elem][name]; exist { + if instance, err := concrete.make(c); err == nil { + reflect.ValueOf(abstraction).Elem().Set(reflect.ValueOf(instance)) + return nil + } else { + return fmt.Errorf("container: encountered error while making concrete for: %s. Error encountered: %w", elem.String(), err) + } + } + + return errors.New("container: no concrete found for: " + elem.String()) + } + + return errors.New("container: invalid abstraction") +} + +// Fill takes a struct and resolves the fields with the tag `container:"inject"` +func (c Container) Fill(structure interface{}) error { + receiverType := reflect.TypeOf(structure) + if receiverType == nil { + return errors.New("container: invalid structure") + } + + if receiverType.Kind() == reflect.Ptr { + elem := receiverType.Elem() + if elem.Kind() == reflect.Struct { + s := reflect.ValueOf(structure).Elem() + + for i := 0; i < s.NumField(); i++ { + f := s.Field(i) + + if t, exist := s.Type().Field(i).Tag.Lookup("container"); exist { + var name string + + if t == "type" { + name = "" + } else if t == "name" { + name = s.Type().Field(i).Name + } else { + return fmt.Errorf("container: %v has an invalid struct tag", s.Type().Field(i).Name) + } + + if concrete, exist := c[f.Type()][name]; exist { + instance, err := concrete.make(c) + if err != nil { + return err + } + + ptr := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem() + ptr.Set(reflect.ValueOf(instance)) + + continue + } + + return fmt.Errorf("container: cannot make %v field", s.Type().Field(i).Name) + } + } + + return nil + } + } + + return errors.New("container: invalid structure") +} diff --git a/vendor/github.com/golobby/container/v3/global.go b/vendor/github.com/golobby/container/v3/global.go new file mode 100644 index 0000000..4b8d4fe --- /dev/null +++ b/vendor/github.com/golobby/container/v3/global.go @@ -0,0 +1,69 @@ +package container + +// Global is the global concrete of the Container. +var Global = New() + +// Singleton calls the same method of the global concrete. +func Singleton(resolver interface{}) error { + return Global.Singleton(resolver) +} + +// SingletonLazy calls the same method of the global concrete. +func SingletonLazy(resolver interface{}) error { + return Global.SingletonLazy(resolver) +} + +// NamedSingleton calls the same method of the global concrete. +func NamedSingleton(name string, resolver interface{}) error { + return Global.NamedSingleton(name, resolver) +} + +// NamedSingletonLazy calls the same method of the global concrete. +func NamedSingletonLazy(name string, resolver interface{}) error { + return Global.NamedSingletonLazy(name, resolver) +} + +// Transient calls the same method of the global concrete. +func Transient(resolver interface{}) error { + return Global.Transient(resolver) +} + +// TransientLazy calls the same method of the global concrete. +func TransientLazy(resolver interface{}) error { + return Global.TransientLazy(resolver) +} + +// NamedTransient calls the same method of the global concrete. +func NamedTransient(name string, resolver interface{}) error { + return Global.NamedTransient(name, resolver) +} + +// NamedTransientLazy calls the same method of the global concrete. +func NamedTransientLazy(name string, resolver interface{}) error { + return Global.NamedTransientLazy(name, resolver) +} + +// Reset calls the same method of the global concrete. +func Reset() { + Global.Reset() +} + +// Call calls the same method of the global concrete. +func Call(receiver interface{}) error { + return Global.Call(receiver) +} + +// Resolve calls the same method of the global concrete. +func Resolve(abstraction interface{}) error { + return Global.Resolve(abstraction) +} + +// NamedResolve calls the same method of the global concrete. +func NamedResolve(abstraction interface{}, name string) error { + return Global.NamedResolve(abstraction, name) +} + +// Fill calls the same method of the global concrete. +func Fill(receiver interface{}) error { + return Global.Fill(receiver) +} diff --git a/vendor/github.com/golobby/container/v3/must.go b/vendor/github.com/golobby/container/v3/must.go new file mode 100644 index 0000000..8af8770 --- /dev/null +++ b/vendor/github.com/golobby/container/v3/must.go @@ -0,0 +1,85 @@ +package container + +// MustSingleton wraps the `Singleton` method and panics on errors instead of returning the errors. +func MustSingleton(c Container, resolver interface{}) { + if err := c.Singleton(resolver); err != nil { + panic(err) + } +} + +// MustSingleton wraps the `SingletonLazy` method and panics on errors instead of returning the errors. +func MustSingletonLazy(c Container, resolver interface{}) { + if err := c.SingletonLazy(resolver); err != nil { + panic(err) + } +} + +// MustNamedSingleton wraps the `NamedSingleton` method and panics on errors instead of returning the errors. +func MustNamedSingleton(c Container, name string, resolver interface{}) { + if err := c.NamedSingleton(name, resolver); err != nil { + panic(err) + } +} + +// MustNamedSingleton wraps the `NamedSingletonLazy` method and panics on errors instead of returning the errors. +func MustNamedSingletonLazy(c Container, name string, resolver interface{}) { + if err := c.NamedSingletonLazy(name, resolver); err != nil { + panic(err) + } +} + +// MustTransient wraps the `Transient` method and panics on errors instead of returning the errors. +func MustTransient(c Container, resolver interface{}) { + if err := c.Transient(resolver); err != nil { + panic(err) + } +} + +// MustTransientLazy wraps the `TransientLazy` method and panics on errors instead of returning the errors. +func MustTransientLazy(c Container, resolver interface{}) { + if err := c.TransientLazy(resolver); err != nil { + panic(err) + } +} + +// MustNamedTransient wraps the `NamedTransient` method and panics on errors instead of returning the errors. +func MustNamedTransient(c Container, name string, resolver interface{}) { + if err := c.NamedTransient(name, resolver); err != nil { + panic(err) + } +} + +// MustNamedTransient wraps the `NamedTransientLazy` method and panics on errors instead of returning the errors. +func MustNamedTransientLazy(c Container, name string, resolver interface{}) { + if err := c.NamedTransientLazy(name, resolver); err != nil { + panic(err) + } +} + +// MustCall wraps the `Call` method and panics on errors instead of returning the errors. +func MustCall(c Container, receiver interface{}) { + if err := c.Call(receiver); err != nil { + panic(err) + } +} + +// MustResolve wraps the `Resolve` method and panics on errors instead of returning the errors. +func MustResolve(c Container, abstraction interface{}) { + if err := c.Resolve(abstraction); err != nil { + panic(err) + } +} + +// MustNamedResolve wraps the `NamedResolve` method and panics on errors instead of returning the errors. +func MustNamedResolve(c Container, abstraction interface{}, name string) { + if err := c.NamedResolve(abstraction, name); err != nil { + panic(err) + } +} + +// MustFill wraps the `Fill` method and panics on errors instead of returning the errors. +func MustFill(c Container, receiver interface{}) { + if err := c.Fill(receiver); err != nil { + panic(err) + } +} |
