79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package depinject
|
|
|
|
import (
|
|
"reflect"
|
|
)
|
|
|
|
// ModuleKey is a special type used to scope a provider to a "module".
|
|
//
|
|
// Special module-scoped providers can be used with Provide and ProvideInModule
|
|
// by declaring a provider with an input parameter of type ModuleKey. These
|
|
// providers may construct a unique value of a dependency for each module and
|
|
// will be called at most once per module.
|
|
//
|
|
// When being used with ProvideInModule, the provider will not receive its
|
|
// own ModuleKey but rather the key of the module requesting the dependency
|
|
// so that modules can provide module-scoped dependencies to other modules.
|
|
//
|
|
// In order for a module to retrieve their own module key they can define
|
|
// a provider which requires the OwnModuleKey type and DOES NOT require ModuleKey.
|
|
type ModuleKey struct {
|
|
*moduleKey
|
|
}
|
|
|
|
type moduleKey struct {
|
|
name string
|
|
}
|
|
|
|
// Name returns the module key's name.
|
|
func (k ModuleKey) Name() string {
|
|
return k.name
|
|
}
|
|
|
|
// Equals checks if the module key is equal to another module key. Module keys
|
|
// will be equal only if they have the same name and come from the same
|
|
// ModuleKeyContext.
|
|
func (k ModuleKey) Equals(other ModuleKey) bool {
|
|
return k.moduleKey == other.moduleKey
|
|
}
|
|
|
|
var moduleKeyType = reflect.TypeOf(ModuleKey{})
|
|
|
|
// OwnModuleKey is a type which can be used in a module to retrieve its own
|
|
// ModuleKey. It MUST NOT be used together with a ModuleKey dependency.
|
|
type OwnModuleKey ModuleKey
|
|
|
|
var ownModuleKeyType = reflect.TypeOf((*OwnModuleKey)(nil)).Elem()
|
|
|
|
// ModuleKeyContext defines a context for non-forgeable module keys.
|
|
// All module keys with the same name from the same context should be equal
|
|
// and module keys with the same name but from different contexts should be
|
|
// not equal.
|
|
//
|
|
// Usage:
|
|
//
|
|
// moduleKeyCtx := &ModuleKeyContext{}
|
|
// fooKey := moduleKeyCtx.For("foo")
|
|
type ModuleKeyContext struct {
|
|
moduleKeys map[string]*moduleKey
|
|
}
|
|
|
|
// For returns a new or existing module key for the given name within the context.
|
|
func (c *ModuleKeyContext) For(moduleName string) ModuleKey {
|
|
return ModuleKey{c.createOrGetModuleKey(moduleName)}
|
|
}
|
|
|
|
func (c *ModuleKeyContext) createOrGetModuleKey(moduleName string) *moduleKey {
|
|
if c.moduleKeys == nil {
|
|
c.moduleKeys = map[string]*moduleKey{}
|
|
}
|
|
|
|
if k, ok := c.moduleKeys[moduleName]; ok {
|
|
return k
|
|
}
|
|
|
|
k := &moduleKey{moduleName}
|
|
c.moduleKeys[moduleName] = k
|
|
return k
|
|
}
|