GoLang Go-Cloud / Wire проблема с массивом в качестве параметра провайдера - PullRequest
0 голосов
/ 20 ноября 2018

У меня небольшие проблемы с правильной конфигурацией проводов. У меня следующие настройки

Маршрутизатор

func NewRouter(routes []RouterPath) AppRouter {
    r := &appRouter{
        routes: routes,
    }
    return r
}

Интерфейс маршрутизатора

type RouterPath interface {
    Register(root *mux.Router) (p *mux.Router)
}

, и у меня мало контроллеровкоторый в настоящее время реализует этот интерфейс, лучший способ узнать, как создать провод для решения DI, это то, с чем у меня возникла проблема

var routersSet = wire.NewSet(
    routers.NewAuth,
    routers.NewRoot,
    routers.NewUser,
    routers.NewPhpInfo,
)

func RouterProvider(info *routers.PhpInfo, root *routers.Root, user *routers.User) web.AppRouter {
    routes := []web.RouterPath{
        info,
        root,
        user,
    }
    return routers.NewRouter(routes)
}

func Init() Kernel {

    wire.Build(
        routersSet,
        RouterProvider,
        NewKernel,
    )

    return nil
}

, - то, что мне пришлось сделать переходный слой в NewRouter, потому что он ожидает массивмаршруты.Который будет расти очень легко, и определение метода будет легко поддерживать.Я хотел бы видеть smtg, как положить wire.ProviderSet в массив и использовать его в качестве параметра NewRouter, но я не могу понять, как это сделать.

Есть ли лучший способ вместо этого?

1 Ответ

0 голосов
/ 16 января 2019

Трудно увидеть всю картину вашего приложения только из этого небольшого фрагмента, но может быть лучше взять зависимости маршрутизаторов, которые вы создаете в RouterProvider, и просто сконструировать их в функции.

Однако, если вы оцените это и сочтете это неподходящим, у вас все еще есть некоторые варианты.Если вас беспокоит только то, что список аргументов RouterProvider становится длинным, вы можете использовать провайдера структуры:

type routers struct {
  Info *routers.PhpInfo
  Root *routers.Root
  User *routers.User
}

func RouterProvider(r routers) web.AppRouter {
  return routers.NewRouter([]RouterPath{
    r.Info,
    r.Root,
    r.User,
  })
}

Если это действительно громоздко, вы можете использовать отражение, чтобы сжать поля вчасть:

type routers struct {
  Info *routers.PhpInfo
  Root *routers.Root
  User *routers.User
}

func RouterProvider(r routers) web.AppRouter {
  value := reflect.ValueOf(r)
  var paths []RouterPath
  for i := 0; i < value.NumField(); i++ {
    if p, ok := value.Field(i).Interface().(RouterPath); ok {
      paths = append(paths, p)
    }
  }
  return routers.NewRouter(paths)
}

Я действительно рекомендовал бы первый подход, потому что для кого-то, кто читает ваш код, гораздо понятнее, что происходит.Reflection всегда перемещает разрывы во время выполнения, а не во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...