2016-09-25 3 views
1

Исходя из фона Java, у меня есть некоторые вопросы о том, как обычно делаются в Голанге. Я специально говорю об услугах и дао/репозиториях.Golang service/daos реализация

В java я бы использовал инъекцию зависимостей (возможно, как singleton/application-scoped), и у меня была служба, введенная в мою конечную точку/ресурс отдыха.

Чтобы дать немного больше контекста. Представьте себе следующую 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) 
} 

скопировал это прямо из моего кода, основной и инициализации расколоты, потому что Google App Engine.

Так что на данный момент у меня есть один обработчик. В этом обработчике я ожидаю взаимодействия с BlogService.

Вопрос в том, где и в какой области следует создавать экземпляр структуры BlogService и дамо, например, структуры данных?

Должен ли я делать это каждый раз, когда обработчик запускается или делает его постоянным/глобальным?

Для полноты, вот обработчик и 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), если вы строите все необходимые зависимости во время запроса/response (что необходимо избегать условий гонки, за исключением зависимостей, которые управляют параллелизмом самостоятельно, например 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

Хорошая точка. Чтобы я правильно понял; сделать ненулевой пустой контекст, используя функцию фона контекстного пакета, инициализировать и загрузить службы в структуре контейнера, поместить эту структуру контейнера в контекст и использовать это в обработчиках? –

Смежные вопросы