Go-如何组织动态包的代码

Go-如何组织动态包的代码,go,Go,我有一个用Go编写的小型web应用程序。它是为一个更大的系统创建的基础,我希望它是可扩展的,可以添加/删除组件,而不需要以任何方式修改这个基础 目前的结构是: App Modules Core ... Core Files Here ... app.go main.go app.go将包含一个路由方法,该方法应接受web请求,并根据请求路径知道哪个模块负责处理请求。每个模块/组件在控

我有一个用Go编写的小型web应用程序。它是为一个更大的系统创建的基础,我希望它是可扩展的,可以添加/删除组件,而不需要以任何方式修改这个基础

目前的结构是:

       App
         Modules
             Core
                 ... Core Files Here ...
       app.go
   main.go
app.go将包含一个路由方法,该方法应接受web请求,并根据请求路径知道哪个模块负责处理请求。每个模块/组件在控制器上都有自己的接口

每个组件都有自己的包名,所以我认为这是不可能的,因为go强制显式导入

例如,我可以添加一个名为say blog的新模块/组件,例如:

       App
         Modules
             Core
                 ... Core Files Here ...
                 controller.go
             Blog
                 ... Blog Files Here ...
                 controller.go
       app.go
   main.go

有几种方法可以实现你的目标。由于Go目前不支持动态加载的库,因此在添加/删除任何组件时,您可能需要重新编译应用程序。因此,最简单的方法是
yourapp/core
包,其中包含以下内容:

  • 一个
    应用程序
    类型,带有充当主应用程序的
    servehtp
    方法
  • 所有组件都必须实现的
    组件
    接口。您可能需要在其中包含一个
    BaseUrl()字符串和一个
    ServeHTTP
    方法
  • 注册
    方法添加到您的
    应用程序
    类型,可用于向应用程序添加新组件
然后,您的组件可以在单独的包中实现(例如,
yourapp/blog
),它们可能取决于您的
yourapp/core

唯一需要“用户可编辑”的是
main.go
文件,该文件可能如下所示:

func main() {
    app := core.NewApplication()
    app.Register(blog.Blog{
        Title: "My Personal Blog",
    })
    app.Register(...)
    app.Run()
}
另一种方法可能是为组件定义RPC接口(可能包括
RegisterComponent
UnregisterComponent
GetGlobalConfig
等函数)


然后,您可以在单独的进程中运行这些组件,其优点是您可以动态启动/停止/重新加载这些组件,并且它们不会破坏您的主应用程序。看看这个软件包,也许你想用这个方法来代替。

。一种变体可能是,每个组件都在init()函数中执行
core.Register(…)