Golang服务/ daos实现

时间:2016-09-25 17:45:14

标签: go architecture dao

来自Java背景,我对如何在Golang中完成工作有一些疑问。我特别谈论服务和dao /存储库。

在java中,我会使用依赖注入(可能是singleton / application-scoped),并将一个Service注入到我的rest端点/资源中。

提供更多背景信息。想象一下以下Golang代码:

func main() {
    http.ListenAndServe("localhost:8080", nil)
}

func init() {
    r := httptreemux.New()
    api := r.NewGroup("/api/v1")
    api.GET("/blogs", GetAllBlogs)
    http.Handle("/", r)
}

直接从我的代码复制此内容,main和init因为谷歌应用引擎而被拆分。

所以现在我有一个处理程序。在该处理程序中,我希望与BlogService进行交互。

问题是,我应该在何处以及在什么范围内实例化BlogService结构和dao之类的数据结构?

我是应该每次触发处理程序时执行此操作,还是将其设置为常量/全局?

为了完整性,这里是处理程序和blogService:

// GetAllBlogs Retrieves all blogs from GCloud datastore
func GetAllBlogs(w http.ResponseWriter, req *http.Request, params map[string]string) {
    c := appengine.NewContext(req)
   // need a reference to Blog Service at this point, where to instantiate?
}

type blogService struct{}

// Blog contains the content and meta data for a blog post.
type Blog struct {...}

// newBlogService constructs a new service to operate on Blogs.
func newBlogService() *blogService {
    return &blogService{}
}

func (s *blogService) ListBlogs(ctx context.Context) ([]*Blog, error)    {
    // Do some dao-ey / repository things, where to instantiate BlogDao?
}

1 个答案:

答案 0 :(得分:2)

如果您在请求/响应周期中构建了所有必需的依赖项,那么您可以使用context.Context将请求范围值传递给处理程序(在Go 1.7中可用)(您应该避免竞争条件,除了像sql.DB那样自行管理并发的依赖项。例如,将所有服务放入单个容器中,然后查询该值的上下文:

container := request.Context.Value("container").(*Container)
blogs,err := container.GetBlogService().ListBlogs()

阅读以下材料:

https://golang.org/pkg/context/

https://golang.org/pkg/net/http/#Request.Context