Go Plugin变量初始化

时间:2017-04-03 09:47:23

标签: go plugins

这是关于Go Plugin初始化的一般问题。

我想在Go程序中创建一个Go包插件。

包(比如mypackage)有一个变量,它使用来自可执行文件中某个包的函数调用进行初始化。 (例如,interface Logger类型的变量,由logger.CreateLogger函数初始化。)

为了使mypackage成为插件,我需要创建一个main包,在mypackage中嵌入main,然后导出一个api Initmain,它接受​​一个可以让我记录器的功能。

我想这样做,以减少我的插件的依赖性。 mypackage插件应取决于interface Logger而不是Logger的实现。

现在问题是初始化,在可执行的情况下,初始化可能发生如下:

package mypackage

var dlog = logger.CreateLogger("mypackage")

记录器可用于func init()的任何mypackage函数。

转换为插件后,无法像这样进行初始化。它必须在调用main.Init后的稍后时间进行初始化。

插件打开时调用func init,因此不能用于初始化变量。

只有解决方案似乎是为每个包创建一个函数,并从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)        
}

有没有更好的初始化方法?我尝试检查github.com/facebookgo/inject,但无法弄清楚如何在插件中使用它。

1 个答案:

答案 0 :(得分:1)

您的解决方案没有任何问题,但如果您希望能够在变量声明和包init()函数中使用它,那么您就可以这样做。我也认为以这种方式使用插件更容易,但这需要在主应用程序和插件之间使用通用的共享包。

一种选择是创建一个"商店"包,可以存储工厂功能或预先创建的记录器。

我们说Logger接口定义在mylogger中:

package mylogger

type Logger interface { Log(string) }

store例如:

package store

import "mylogger"

var LoggerFactory func(string) mylogger.Logger

在您的主应用中初始化,然后加载/打开mypackage插件:

package main

import "store"

func main() {
    store.LoggerFactory = logger.CreateLogger

    // Now proceed to load / open mypackage plugin
}

然后mypackage插件可能如下所示:

package mypackage

import "store"

var dlog = store.LoggerFactory("mypackage")