Go plugin variable initialization
This is a general question about initializing the Go Plugin.
I want to make a specific package in a Go program for a Go plugin.
A package (say mypackage
) has a variable that is initialized by calling a function from a specific package in the executable. (For example, a variable of a type interface Logger
that needs to be initialized by a function logger.CreateLogger
.)
To make a mypackage
plugin, I need to create a package main
, insert mypackage
inside main
and export the api Init
in a package main
that accepts a function that the registrar can give me.
I want to do this to reduce the dependencies of my plugin. The plugin mypackage
should depend on interface Logger
, not on the version of the Logger.
Now the problem is in the initialization, in the case of an executable file, the initialization could happen as shown below:
package mypackage
var dlog = logger.CreateLogger("mypackage")
And the recorder can be used in any function func init()
mypackage
.
Once converted to a plugin, it cannot be initialized as follows. It must be initialized at a later point after the call main.Init
.
func init
called when the plugin is open, so it cannot be used to initialize variables.
The only solution is to create a function for each package and is called from the exported function in the package main
.
package mypackage
var dlog Logger
func Init(f createLoggerType){
dlog = f()
yetanotherpackage.Init(f)
}
package main
func Init(f createLoogerType) {
mypackage.Init(f)
anotherpackage.Init(f)
}
Is there a better way to initialize? I tried to check github.com/facebookgo/inject
but couldn't figure out how it can be used in case of plugins.
source to share
There is nothing wrong with your solution, but if you want to use it in your package variable and function declarations init()
, here's how you can do it. I also find it easier to use the plugin this way, but it requires a common shared package between your main application and the plugin.
One option is to create a "store" package that can store factory functions or pre-built logs.
Let's say the interface definition Logger
is in mylogger
:
package mylogger
type Logger interface { Log(string) }
store
eg:
package store
import "mylogger"
var LoggerFactory func(string) mylogger.Logger
And in your main application, initialize it before you load / open the plugin mypackage
:
package main
import "store"
func main() {
store.LoggerFactory = logger.CreateLogger
// Now proceed to load / open mypackage plugin
}
Then the plugin mypackage
might look like this:
package mypackage
import "store"
var dlog = store.LoggerFactory("mypackage")
source to share