在golang中如何在配置文件中按名称获取接口实例

时间:2017-05-30 06:04:19

标签: spring go

我想知道如何在golang中灵活地注入依赖,就像java spring一样,如果我想更改接口的实例,我只需要更改一些配置文件。

首先我想找一些像 getTypeByName()这样的函数,所以我可以在配置文件中给出一个像“mypkg.structName”这样的结构名称并通过该函数加载该结构,但似乎golang中没有这样的功能。

现在我能想到的最可行的方法是创建一个加载器模型来生成struct register file以加载所有自定义结构。

但我想知道是否有更简单的方法可以做到这一点,是否有一些golang风格的方式来实现这种灵活性?

1 个答案:

答案 0 :(得分:3)

我认为您的方法是正确的,因为如果在编译期间未定义类型,则无法实例化该类型。否则,您需要使用plugin

我不确定是否更容易,但如果您希望将自定义结构组织在不同的包中,则可以使用与{{1}类似的方法}。

  1. 定义一个工厂包,其中包含database/sql接口和管理已知工厂。此程序包应导出Factory函数以注册自定义工厂,并Register函数用于创建给定类型的实例。例如:

    New
  2. 创建包含自定义结构并实现package factory import ( "strings" "sync" ) type Factory interface { New(name string) (interface{}, bool) } var ( mu sync.RWMutex factories = make(map[string]Factory) ) func Register(pkgName string, f Factory) { mu.Lock() defer mu.Unlock() if f == nil { panic("Factory is nil") } if _, exist := factories[pkgName]; exist { panic("Factory already registered") } factories[pkgName] = f } func New(typeName string) (interface{}, bool) { items := strings.Split(typeName, ".") if len(items) >= 2 { mu.RLock() defer mu.RUnlock() if f, exist := factories[items[0]]; exist { return f.New(items[1]) } } return nil, false } 接口的包。在初始化期间注册工厂,即Factory功能,例如

    init()
  3. 根据需要重复步骤(2)。

  4. 最后,在主包中,您可以按如下方式创建实例:

    package pkga
    
    import "path/to/your/factory"
    
    type thisFactory struct {
    }
    
    type Alpha struct{}
    type Beta struct{}
    type Gamma struct{}
    
    func (f *thisFactory) New(name string) (interface{}, bool) {
        switch name {
        case "Alpha":
            return &Alpha{}, true
        case "Beta":
            return &Beta{}, true
        case "Gamma":
            return &Gamma{}, true
        }
        return nil, false
    }
    
    func init() {
        factory.Register("pkga", &thisFactory{})
    }
    
  5. 更新:提供了一个工作示例here