Я использую фильтр для внедрения зависимостей.
Фильтр проверяет, реализует ли контроллер определенные интерфейсы и вставляет ли правильную зависимость. Вот пример, который вставляет связанную с базой данных зависимость:
func DependencyFilter(c *revel.Controller, filterChain []revel.Filter) {
if ctrl, ok := c.AppController.(DataServiceController); ok {
ctrl.SetDataService(<your dependency>)
}
// Different dependencies could be injected here:
//if ctrl, ok := c.AppController.(FooController); ok {
// ctrl.SetFooService(<your dependency>)
//}
// Call the next filter
if len(filterChain) > 0 {
filterChain[0](c, filterChain[1:])
}
}
Где DataServiceController
:
type DataServiceController interface {
SetDataService(ds services.DataService)
}
Я вставил свой фильтр в качестве предпоследней записи в init.go
:
revel.Filters = []revel.Filter{
revel.PanicFilter, // Recover from panics and display an error page instead.
// ...
DependencyFilter, // Add dependencies
revel.ActionInvoker, // Invoke the action.
}
Большинству моих контроллеров нужны одинаковые зависимости, поэтому у меня есть базовый контроллер, который они все встраивают:
type BaseController struct {
*revel.Controller
DataService services.DataService
}
func (c *BaseController) SetDataService(ds services.DataService) {
c.DataService = ds
}
Итак, мои бетонные контроллеры выглядят так:
type Home struct {
BaseController
}
func (c Home) Index() revel.Result {
// ...
}
Возможно, есть лучшие пути, но это мой подход.