2016-09-25 53 views
1

從Java背景來看,我對Golang中通常做的事情有些疑問。我正在專門討論服務和dao /倉庫。在java中,我會使用依賴注入(可能作爲單例/應用程序範圍),並有一個服務注入我的休息端點/資源。Golang服務/ daos實現

給予更多的上下文。想象一下以下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) 
} 

直接從我的代碼,主要和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? 
} 

回答

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

+0

非常感謝您的回答。有了請求/響應週期,你的意思是爲每個請求實例化一個服務嗎?如果是這樣,爲什麼不直接在處理程序中實例化,而是將它傳遞給它?這對我來說並不完全清楚。對不起,我的困惑。 –

+0

如果你想堆疊中間件並在那之間共享信息會怎樣? – mpm

+0

好點。爲了確保我理解正確;使用上下文包的Background函數創建非零空上下文,在容器結構中初始化和加載服務,將該容器結構放在上下文中,並在處理程序中使用它? –