일반적으로 Go에서는 이벤트가 필요한 경우 아마 채널을 사용해야하지만 플러그인이 필요한 경우 이동 방법은 인터페이스입니다. 다음은 플러그인을 추가하기 위해 앱의 기본 파일에 작성된 코드 인 을 최소화하는 단순한 플러그인 아키텍처의 약간 긴 예제입니다 (자동으로 수행 할 수 있지만 아래에는 dnyamic 참조).
나는 그것이 당신이 찾고있는 방향에 있기를 바랍니다. 플러그인 인터페이스
// All DoerPlugins can do something when you call that method
type DoerPlugin interface {
DoSomething()
}
// All FooerPlugins can Foo() when you want them too
type FooerPlugin interface {
Foo()
}
2. 플러그인 레지스트리
이제, 우리의 핵심 응용 프로그램은 플러그인 레지스트리가 있습니다. 이제 우리는 레지스트리에 플러그인을 추가하는 방법을 노출
package plugin_registry
// These are are registered fooers
var Fooers = []FooerPlugin{}
// Thes are our registered doers
var Doers = []DoerPlugin{}
: 난 그냥 걸쳐 아이디어를 얻을, quicky 더러운 여기서 뭔가를하고 있어요. 간단한 방법은 유형 당 하나를 추가하는 것이지만, 더 복잡한 반사 재료로 이동하고 하나의 기능을 가질 수 있습니다.그러나 일반적으로 이동에서, 이제 간단한
:
package plugin_registry
// Register a FooerPlugin
func RegisterFooer(f FooerPlugin) {
Fooers = append(Fooers, f)
}
// Register a DoerPlugin
func RegisterDoer(d DoerPlugin) {
Doers = append(Doers, d)
}
3. 구현 및 등록 플러그인 물건을 유지하려고이 플러그인 모듈입니다 가정합니다. 우리는 doer 인 플러그인을 만들고, 패키지에 init()
메소드를 등록합니다. 가져온 패키지마다 시작된 프로그램에서 init()이 한 번 발생합니다.
다시 package myplugin
import (
"github.com/myframework/plugin_registry"
)
type MyPlugin struct {
//whatever
}
func (m *MyPlugin)DoSomething() {
fmt.Println("Doing something!")
}
, 여기에 유일한 자동으로 플러그인을 가져 오기
func init() {
my := &MyPlugin{}
plugin_registry.RegisterDoer(my)
}
4. 자동
을 등록 패키지를 등록하고 "초기화 마법"입니다 우리가 바꿀 필요가있는 것은 우리가 주 패키지로 가져 오는 것입니다. Go에는 동적 가져 오기 또는 링크가 없으므로 작성해야하는 유일한 것입니다. 파일 트리 또는 설정 파일을 살펴보고 가져올 모든 플러그인을 찾아 주 파일 을 생성하는 go generate
스크립트를 만드는 것은 매우 간단합니다. 동적은 아니지만 자동화가 가능합니다. main은 등록의 부작용을위한 플러그인을 수입하기 때문에 import uses the blank identifier to avoid unused import error. 응용 프로그램의 핵심에
5.
package main
import (
"github.com/myframework/plugin_registry"
_ "github.com/d00dzzzzz/myplugin" //importing this will automaticall register the plugin
)
그리고 지금 우리의 핵심 응용 프로그램은 플러그인과 상호 작용 할 수 있도록 변경하는 코드를 필요로하지 않는다 :
func main() {
for _, d := range plugin_registry.Doers {
d.DoSomething()
}
for _, f := range plugin_registry.Fooers {
f.Foo()
}
}
그리고 그것에 관한 것입니다. 플러그인 레지스트리는 앱의 핵심 패키지와 플러그인을 모두 가져올 수있는 별도의 패키지 이어야하므로 순환 가져 오기 기능을 사용할 수 없습니다.
물론이 믹스에 이벤트 처리기를 추가 할 수는 있지만, 필자가 시연했듯이 필요하지는 않습니다.
플러그인 아키텍처의 예는 database/sql 및 database/sql/driver 패키지를 참조하십시오. 이 아키텍처에서는 init() 함수에서 plugins [register] (http://godoc.org/database/sql#Register)를 호출하고 드라이버 패키지에서 정의한대로 인터페이스를 구현합니다. –