Documentation ¶
Overview ¶
Package plugin provides a generic inversion of control model for making extensible Go packages, libraries, and applications. Like github.com/progrium/go-extpoints, but reflect based: doesn't require code generation, but have more overhead; provide more flexibility, but less type safety. It allows to register constructor for some plugin interface, and create new plugin instances or plugin instance factories. Main feature is flexible plugin configuration: plugin factory can accept config struct, that could be filled by passed hook. Config default values could be provided by registering default config factory. Such flexibility can be used to decode structured text (json/yaml/etc) into struct.
Type expectations. Here and bellow we mean by <someTypeName> some type expectations. [some type signature part] means that this part of type signature is optional.
Plugin type, let's label it as <plugin>, should be interface. Registered plugin constructor should be one of: <newPlugin> or <newFactory>. <newPlugin> should have type func([config <configType>]) (<pluginImpl>[, error]). <newFactory> should have type func([config <configType]) (func() (<pluginImpl>[, error])[, error]). <pluginImpl> should be assignable to <plugin>. That is, <plugin> methods should be subset <pluginImpl> methods. In other words, <pluginImpl> should be some <plugin> implementation, <plugin> or interface, that contains <plugin> methods as subset. <configType> type should be struct or struct pointer.
Index ¶
- func FactoryPluginType(factoryType reflect.Type) (plugin reflect.Type, ok bool)
- func Lookup(pluginType reflect.Type) bool
- func LookupFactory(factoryType reflect.Type) bool
- func New(pluginType reflect.Type, name string, ...) (plugin interface{}, err error)
- func NewFactory(factoryType reflect.Type, name string, ...) (factory interface{}, err error)
- func PtrType(ptr interface{}) reflect.Type
- func Register(pluginType reflect.Type, name string, newPluginImpl interface{}, ...)
- type Registry
- func (r *Registry) Lookup(pluginType reflect.Type) bool
- func (r *Registry) LookupFactory(factoryType reflect.Type) bool
- func (r *Registry) New(pluginType reflect.Type, name string, ...) (plugin interface{}, err error)
- func (r *Registry) NewFactory(factoryType reflect.Type, name string, ...) (factory interface{}, err error)
- func (r *Registry) Register(pluginType reflect.Type, name string, constructor interface{}, ...)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FactoryPluginType ¶
FactoryPluginType returns (SomeInterface, true) if factoryType looks like func() (SomeInterface[, error]) or (nil, false) otherwise.
func LookupFactory ¶
LookupFactory is DefaultRegistry().LookupFactory shortcut.
func New ¶
func New(pluginType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (plugin interface{}, err error)
New is DefaultRegistry().New shortcut.
func NewFactory ¶
func NewFactory(factoryType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (factory interface{}, err error)
NewFactory is DefaultRegistry().NewFactory shortcut.
func PtrType ¶
PtrType is helper to extract plugin types. Example: plugin.PtrType((*PluginInterface)(nil)) instead of reflect.TypeOf((*PluginInterface)(nil)).Elem()
func Register ¶
func Register( pluginType reflect.Type, name string, newPluginImpl interface{}, newDefaultConfigOptional ...interface{}, )
Register is DefaultRegistry().Register shortcut.
Example ¶
package main import "github.com/yandex/pandora/core/plugin" type Plugin interface { DoSmth() } func RegisterPlugin(name string, newPluginImpl interface{}, newDefaultConfigOptional ...interface{}) { var p Plugin plugin.Register(plugin.PtrType(&p), name, newPluginImpl, newDefaultConfigOptional...) } func main() { type Conf struct{ Smth string } New := func(Conf) Plugin { panic("") } RegisterPlugin("no-default", New) RegisterPlugin("default", New, func() Conf { return Conf{"example"} }) }
Output:
Types ¶
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
func DefaultRegistry ¶
func DefaultRegistry() *Registry
DefaultRegistry returns default Registry used for package Registry like functions.
func NewRegistry ¶
func NewRegistry() *Registry
func (*Registry) Lookup ¶
Lookup returns true if any plugin constructor has been registered for given type.
func (*Registry) LookupFactory ¶
LookupFactory returns true if factoryType looks like func() (SomeInterface[, error]) and any plugin constructor has been registered for SomeInterface. That is, you may create instance of this factoryType using this registry.
func (*Registry) New ¶
func (r *Registry) New(pluginType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (plugin interface{}, err error)
New creates plugin using registered plugin constructor. Returns error if creation failed or no plugin were registered for given type and name. Passed fillConf called on created config before calling plugin factory. fillConf argument is always valid struct pointer, even if plugin factory receives no config: fillConf is called on empty struct pointer in such case. fillConf error fails plugin creation. New is thread safe, if there is no concurrent Register calls.
func (*Registry) NewFactory ¶
func (r *Registry) NewFactory(factoryType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (factory interface{}, err error)
NewFactory behaves like New, but creates factory func() (PluginInterface[, error]), that on call creates New plugin by registered factory. If registered constructor is <newPlugin> config is created filled for every factory call, if <newFactory, that only once for factory creation.
func (*Registry) Register ¶
func (r *Registry) Register( pluginType reflect.Type, name string, constructor interface{}, newDefaultConfigOptional ...interface{}, )
Register registers plugin constructor and optional default config factory, for given plugin interface type and plugin name. See package doc for type expectations details. Register designed to be called in package init func, so it panics if something go wrong. Panics if type expectations are violated. Panics if some constructor have been already registered for this (pluginType, name) pair. Register is thread unsafe.
If constructor receive config argument, default config factory can be registered. Default config factory type should be: is func() <configType>. Default config factory is optional. If no default config factory has been registered, than plugin factory will receive zero config (zero struct or pointer to zero struct). Registered constructor will never receive nil config, even there are no registered default config factory, or default config is nil. Config will be pointer to zero config in such case.
Directories ¶
Path | Synopsis |
---|---|
Package pluginconfig contains integration plugin with config packages.
|
Package pluginconfig contains integration plugin with config packages. |