3

我对正确配置电线没有什么问题我有以下设置

路由器

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 的参数,但我不知道如何做到这一点。

有没有更好的方法来代替这个?

4

1 回答 1

3

仅从这个小片段中很难看到应用程序的全貌,但最好考虑您正在构建的路由器的依赖关系,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)
}

不过,我真的推荐第一种方法,因为阅读您的代码的人更清楚发生了什么。反射总是将破坏转移到运行时而不是编译时。

于 2019-01-15T22:58:23.980 回答