问题描述
给出以下代码:
package main
import (
"fmt"
)
type datstr string
type Guy interface {
SomeDumbGuy() string
}
func (d *datstr) SomeDumbGuy() string {
return "some guy"
}
func someConsumer(g Guy) {
fmt.Println("Hello, " + g.SomeDumbGuy())
}
func main() {
var d datstr
someConsumer(&d)
}
在 main 中完成的组件连接是否是将依赖关系连接在一起的正确方法?似乎我在代码中有点用完了.有没有比这更好的通用模式了?还是我想得太多了?
Is the wiring of components together that's done in main the right way to wire a dependency together? It seems like I'm over using this a bit in my code. Is there a common pattern better than this, or am I overthinking it?
推荐答案
是的,facebookgo注入库允许您获取注入的成员并为您连接图.
Yes, the facebookgo inject library allows you to take your injected members and will wire up the graph for you.
这是文档中的代码示例:
Here's a code example from the documentation:
package main
import (
"fmt"
"net/http"
"os"
"github.com/facebookgo/inject"
)
// Our Awesome Application renders a message using two APIs in our fake
// world.
type HomePlanetRenderApp struct {
// The tags below indicate to the inject library that these fields are
// eligible for injection. They do not specify any options, and will
// result in a singleton instance created for each of the APIs.
NameAPI *NameAPI `inject:""`
PlanetAPI *PlanetAPI `inject:""`
}
func (a *HomePlanetRenderApp) Render(id uint64) string {
return fmt.Sprintf(
"%s is from the planet %s.",
a.NameAPI.Name(id),
a.PlanetAPI.Planet(id),
)
}
// Our fake Name API.
type NameAPI struct {
// Here and below in PlanetAPI we add the tag to an interface value.
// This value cannot automatically be created (by definition) and
// hence must be explicitly provided to the graph.
HTTPTransport http.RoundTripper `inject:""`
}
func (n *NameAPI) Name(id uint64) string {
// in the real world we would use f.HTTPTransport and fetch the name
return "Spock"
}
// Our fake Planet API.
type PlanetAPI struct {
HTTPTransport http.RoundTripper `inject:""`
}
func (p *PlanetAPI) Planet(id uint64) string {
// in the real world we would use f.HTTPTransport and fetch the planet
return "Vulcan"
}
func main() {
// Typically an application will have exactly one object graph, and
// you will create it and use it within a main function:
var g inject.Graph
// We provide our graph two "seed" objects, one our empty
// HomePlanetRenderApp instance which we're hoping to get filled out,
// and second our DefaultTransport to satisfy our HTTPTransport
// dependency. We have to provide the DefaultTransport because the
// dependency is defined in terms of the http.RoundTripper interface,
// and since it is an interface the library cannot create an instance
// for it. Instead it will use the given DefaultTransport to satisfy
// the dependency since it implements the interface:
var a HomePlanetRenderApp
err := g.Provide(
&inject.Object{Value: &a},
&inject.Object{Value: http.DefaultTransport},
)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Here the Populate call is creating instances of NameAPI &
// PlanetAPI, and setting the HTTPTransport on both to the
// http.DefaultTransport provided above:
if err := g.Populate(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// There is a shorthand API for the simple case which combines the
// three calls above is available as inject.Populate:
//
// inject.Populate(&a, http.DefaultTransport)
//
// The above API shows the underlying API which also allows the use of
// named instances for more complex scenarios.
fmt.Println(a.Render(42))
}
这篇关于在golang中是否有更好的依赖注入模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!