英文:
Golang auto-including extensible application
问题
我对Go语言还比较新,想知道是否有一种已经建立的设计模式来实现可扩展的应用程序。
例如,在我的源代码中,我有一个extensions目录,用于放置程序的不同应用特定扩展。目前,我通过名称在我的main函数中逐个加载每个扩展。我希望在编译程序时自动包含我的扩展。
只是为了明确,我不是在尝试在运行时动态加载扩展。我只是希望将扩展添加到程序中变得简单:
- 将文件放入extensions文件夹中
- 重新编译
如果Go语言无法实现这一点,那我会尽力而为,但我只是在想是否有更好的方法来做到这一点。
为了更清楚地展示我想要简化的内容,这里有一个我现在的示例:
main.go
package main
import (
"github.com/go-martini/martini"
"gopath/project/extensions"
)
func main() {
app := martini.Classic()
// 启用每个扩展
app.Router.Group("/example", extensions.Example)
// app.Router.Group("/example2", extensions.Example2)
// ...
app.Run()
}
extensions/example.go
package extensions
import (
"github.com/codegangsta/martini-contrib/render"
"github.com/go-martini/martini"
)
func Example(router martini.Router) {
router.Get("", func(r render.Render) {
// 响应查询
r.JSON(200, "")
})
}
英文:
I am fairly new to Go and am curious if there is an established design pattern for extensible applications.
For example, in my source I have an extensions directory where I place different application specific extensions for my program. I currently load each in my main function individually by name. I would like to have the program auto-include my extensions when it gets compiled.
Just to be clear, I am not trying to dynamically load extensions at runtime. I would just like to make adding an extension to the program as simple as:
- Drop file in extensions folder
- Recompile
If this is just not possible with Go then I'll make due, but I'm just thinking there has to be a better way to do this.
To show more clearly what I want to make simpler, here is an example of what I do now:
main.go
package main
import (
"github.com/go-martini/martini"
"gopath/project/extensions"
)
func main() {
app := martini.Classic()
// Enable Each Extension
app.Router.Group("/example", extensions.Example)
// app.Router.Group("/example2", extensions.Example2)
// ...
app.Run()
}
extensions/example.go
package extensions
import (
"github.com/codegangsta/martini-contrib/render"
"github.com/go-martini/martini"
)
func Example(router martini.Router) {
router.Get("", func(r render.Render) {
// respond to query
r.JSON(200, "")
})
}
答案1
得分: 4
在每个扩展的go文件中使用一个init
方法来注册扩展。
所以在plugin1.go
中你会写:
func init() {
App.Router.Group("/example", extensions.Example)
}
你需要将app
设置为公共的。
你也可以在主代码中使用注册函数。
我在rclone中使用这种技术:这是注册函数,这是它被调用的示例。这些模块都是通过将它们包含在主包中进行编译的。
英文:
Use an init
method in each extension go file to register the extension.
So in plugin1.go
you'd write
func init() {
App.Router.Group("/example", extensions.Example)
}
You'd need to make app
public.
You could use a registration function in the main code instead.
I use this technique in rclone: Here is the registration function and here is an example of it being called. The modules are each compiled in by including them in the main pacakge
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论