From e209bf696016db79103bc9f68c67c85343fb7ef4 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Thu, 1 Sep 2022 11:53:47 -0400 Subject: [PATCH 1/3] feat(depinject): allow module keys to manually be created for manual wiring --- depinject/config.go | 4 ++-- depinject/container.go | 13 ++----------- depinject/module_key.go | 26 ++++++++++++++++++++++++++ depinject/module_key_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 depinject/module_key_test.go diff --git a/depinject/config.go b/depinject/config.go index ff947bc627bd..f43a4bac1633 100644 --- a/depinject/config.go +++ b/depinject/config.go @@ -36,7 +36,7 @@ func ProvideInModule(moduleName string, providers ...interface{}) Config { return errors.Errorf("expected non-empty module name") } - return provide(ctr, ctr.createOrGetModuleKey(moduleName), providers) + return provide(ctr, ctr.moduleKeyContext.createOrGetModuleKey(moduleName), providers) }) } @@ -83,7 +83,7 @@ func InvokeInModule(moduleName string, invokers ...interface{}) Config { return errors.Errorf("expected non-empty module name") } - return invoke(ctr, ctr.createOrGetModuleKey(moduleName), invokers) + return invoke(ctr, ctr.moduleKeyContext.createOrGetModuleKey(moduleName), invokers) }) } diff --git a/depinject/container.go b/depinject/container.go index d2998f585828..148a8c28ccdd 100644 --- a/depinject/container.go +++ b/depinject/container.go @@ -17,7 +17,7 @@ type container struct { interfaceBindings map[string]interfaceBinding invokers []invoker - moduleKeys map[string]*moduleKey + moduleKeyContext *ModuleKeyContext resolveStack []resolveFrame callerStack []Location @@ -48,7 +48,7 @@ func newContainer(cfg *debugConfig) *container { return &container{ debugConfig: cfg, resolvers: map[string]resolver{}, - moduleKeys: map[string]*moduleKey{}, + moduleKeyContext: &ModuleKeyContext{}, interfaceBindings: map[string]interfaceBinding{}, callerStack: nil, callerMap: map[Location]bool{}, @@ -498,15 +498,6 @@ func (c *container) build(loc Location, outputs ...interface{}) error { return nil } -func (c container) createOrGetModuleKey(name string) *moduleKey { - if s, ok := c.moduleKeys[name]; ok { - return s - } - s := &moduleKey{name} - c.moduleKeys[name] = s - return s -} - func (c container) formatResolveStack() string { buf := &bytes.Buffer{} _, _ = fmt.Fprintf(buf, "\twhile resolving:\n") diff --git a/depinject/module_key.go b/depinject/module_key.go index ff8902a44202..8f75a94e9891 100644 --- a/depinject/module_key.go +++ b/depinject/module_key.go @@ -29,6 +29,10 @@ func (k ModuleKey) Name() string { return k.name } +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 @@ -36,3 +40,25 @@ var moduleKeyType = reflect.TypeOf(ModuleKey{}) type OwnModuleKey ModuleKey var ownModuleKeyType = reflect.TypeOf((*OwnModuleKey)(nil)).Elem() + +type ModuleKeyContext struct { + moduleKeys map[string]*moduleKey +} + +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 +} diff --git a/depinject/module_key_test.go b/depinject/module_key_test.go new file mode 100644 index 000000000000..5a226c0e363e --- /dev/null +++ b/depinject/module_key_test.go @@ -0,0 +1,25 @@ +package depinject + +import ( + "testing" + + "gotest.tools/v3/assert" +) + +func TestModuleKeyEquals(t *testing.T) { + ctx := &ModuleKeyContext{} + + fooKey := ctx.For("foo") + fooKey2 := ctx.For("foo") + // two foo keys from the same context should be equal + assert.Assert(t, fooKey.Equals(fooKey2)) + + barKey := ctx.For("bar") + // foo and bar keys should be not equal + assert.Assert(t, !fooKey.Equals(barKey)) + + ctx2 := &ModuleKeyContext{} + fooKeyFromAnotherCtx := ctx2.For("foo") + // foo keys from different context should be not equal + assert.Assert(t, !fooKey.Equals(fooKeyFromAnotherCtx)) +} From a54e52f0e2660b6be8886f0e5b17e1518df47db6 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Thu, 1 Sep 2022 11:58:01 -0400 Subject: [PATCH 2/3] add docs --- depinject/module_key.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/depinject/module_key.go b/depinject/module_key.go index 8f75a94e9891..5fe60db33543 100644 --- a/depinject/module_key.go +++ b/depinject/module_key.go @@ -25,10 +25,14 @@ 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 } @@ -41,10 +45,19 @@ type OwnModuleKey ModuleKey var ownModuleKeyType = reflect.TypeOf((*OwnModuleKey)(nil)).Elem() +// ModuleKeyContext context defines a context for non-forgeable module keys. +// All module keys with the same name in 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)} } From 534f081bf8994c73a35e24a716cda56926825c8f Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Thu, 1 Sep 2022 11:58:52 -0400 Subject: [PATCH 3/3] fix docs --- depinject/module_key.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depinject/module_key.go b/depinject/module_key.go index 5fe60db33543..8fba64f9436a 100644 --- a/depinject/module_key.go +++ b/depinject/module_key.go @@ -45,8 +45,8 @@ type OwnModuleKey ModuleKey var ownModuleKeyType = reflect.TypeOf((*OwnModuleKey)(nil)).Elem() -// ModuleKeyContext context defines a context for non-forgeable module keys. -// All module keys with the same name in the same context should be equal +// 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. //