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.

+3


source to share


1 answer


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")

      

+1


source







All Articles