From 024f6f8144e0ae1ac4a258e5e9c506ca97c0e4ed Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Wed, 25 Oct 2023 11:14:27 -0700 Subject: [PATCH] Update Get interface to GetSingle Remove the `Get` which just returns the first instance while ignoring other instances. GetSingle will ensure that there is only a single instance of a plugin and allow dependencies to enforce it or have logic to select the right plugin. Signed-off-by: Derek McGowan --- context.go | 23 ++++++++++++++++++----- plugin.go | 2 ++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/context.go b/context.go index 7ebe64b..81e5e20 100644 --- a/context.go +++ b/context.go @@ -128,12 +128,25 @@ func (ps *Set) GetAll() []*Plugin { return ps.ordered } -// Get returns the first plugin by its type -func (i *InitContext) Get(t Type) (interface{}, error) { - for _, v := range i.plugins.byTypeAndID[t] { - return v.Instance() +// GetSingle returns a plugin instance of the given type when only a single instance +// of that type is expected. Throws an ErrPluginNotFound if no plugin is found and +// ErrPluginMultipleInstances when multiple instances are found. +// Since plugins are not ordered, if multiple instances is suported then +// GetByType should be used. If only one is expected, then to switch plugins, +// disable or remove the unused plugins of the same type. +func (i *InitContext) GetSingle(t Type) (interface{}, error) { + pt, ok := i.plugins.byTypeAndID[t] + if !ok || len(pt) == 0 { + return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound) + } + if len(pt) > 1 { + return nil, fmt.Errorf("multiple plugins registered for %s: %w", t, ErrPluginMultipleInstances) } - return nil, fmt.Errorf("no plugins registered for %s: %w", t, ErrPluginNotFound) + var p *Plugin + for _, v := range pt { + p = v + } + return p.Instance() } // Plugins returns plugin set diff --git a/plugin.go b/plugin.go index d68c501..f7899e1 100644 --- a/plugin.go +++ b/plugin.go @@ -37,6 +37,8 @@ var ( ErrPluginInitialized = errors.New("plugin: already initialized") // ErrPluginNotFound is used when a plugin is looked up but not found ErrPluginNotFound = errors.New("plugin: not found") + // ErrPluginMultipleInstances is used when a plugin is expected a single instance but has multiple + ErrPluginMultipleInstances = errors.New("plugin: multiple instances") // ErrInvalidRequires will be thrown if the requirements for a plugin are // defined in an invalid manner.